From patchwork Tue Jan 17 12:47:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mimi Zohar X-Patchwork-Id: 9521005 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2E8FB6020A for ; Tue, 17 Jan 2017 13:38:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 13F4B2853C for ; Tue, 17 Jan 2017 13:38:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 088DA2855B; Tue, 17 Jan 2017 13:38:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C757A2853C for ; Tue, 17 Jan 2017 13:38:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751059AbdAQNiN (ORCPT ); Tue, 17 Jan 2017 08:38:13 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:39490 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751053AbdAQNiL (ORCPT ); Tue, 17 Jan 2017 08:38:11 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v0HCi1KR108307 for ; Tue, 17 Jan 2017 07:47:33 -0500 Received: from e23smtp02.au.ibm.com (e23smtp02.au.ibm.com [202.81.31.144]) by mx0a-001b2d01.pphosted.com with ESMTP id 28126g67tq-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 17 Jan 2017 07:47:32 -0500 Received: from localhost by e23smtp02.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 17 Jan 2017 22:47:30 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp02.au.ibm.com (202.81.31.208) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 17 Jan 2017 22:47:28 +1000 Received: from d23relay09.au.ibm.com (d23relay09.au.ibm.com [9.185.63.181]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id A25303578056 for ; Tue, 17 Jan 2017 23:47:27 +1100 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay09.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v0HClRVB2556256 for ; Tue, 17 Jan 2017 23:47:27 +1100 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v0HClRHh029839 for ; Tue, 17 Jan 2017 23:47:27 +1100 Received: from localhost.localdomain ([9.80.91.140]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v0HClPX8029778; Tue, 17 Jan 2017 23:47:26 +1100 Subject: [PATCH] ima: fix ima_d_path() possible race with rename From: Mimi Zohar To: linux-ima-devel Cc: linux-security-module , Al Viro Date: Tue, 17 Jan 2017 07:47:24 -0500 X-Mailer: Evolution 3.12.11 (3.12.11-1.fc21) Mime-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17011712-0004-0000-0000-000001D4BD5E X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17011712-0005-0000-0000-00000980785F Message-Id: <1484657244.3752.3.camel@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-01-17_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1701170175 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP On failure to return a pathname from ima_d_path(), a pointer to dname is returned, which is subsequently used in the IMA measurement list, the IMA audit records, and other audit logging. Saving the pointer to dname for later use has the potential to race with rename. Instead of returning a pointer to dname on failure, this patch returns a pointer to a copy of the filename. Reported-by: Al Viro Signed-off-by: Mimi Zohar --- security/integrity/ima/ima.h | 2 +- security/integrity/ima/ima_api.c | 20 ++++++++++++++++++-- security/integrity/ima/ima_main.c | 8 +++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 5e6180a4da7d..b563fbd4d122 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -204,7 +204,7 @@ int ima_store_template(struct ima_template_entry *entry, int violation, struct inode *inode, const unsigned char *filename, int pcr); void ima_free_template_entry(struct ima_template_entry *entry); -const char *ima_d_path(const struct path *path, char **pathbuf); +const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); /* IMA policy related functions */ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 9df26a2b75ba..d01a52f8f708 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -318,7 +318,17 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, iint->flags |= IMA_AUDITED; } -const char *ima_d_path(const struct path *path, char **pathbuf) +/* + * ima_d_path - return a pointer to the full pathname + * + * Attempt to return a pointer to the full pathname for use in the + * IMA measurement list, IMA audit records, and auditing logs. + * + * On failure, return a pointer to a copy of the filename, not dname. + * Returning a pointer to dname, could result in using the pointer + * after the memory has been freed. + */ +const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf) { char *pathname = NULL; @@ -331,5 +341,11 @@ const char *ima_d_path(const struct path *path, char **pathbuf) pathname = NULL; } } - return pathname ?: (const char *)path->dentry->d_name.name; + + if (!pathname) { + strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX); + pathname = namebuf; + } + + return pathname; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 50818c60538b..d5e492bd2899 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -83,6 +83,7 @@ static void ima_rdwr_violation_check(struct file *file, const char **pathname) { struct inode *inode = file_inode(file); + char filename[NAME_MAX]; fmode_t mode = file->f_mode; bool send_tomtou = false, send_writers = false; @@ -102,7 +103,7 @@ static void ima_rdwr_violation_check(struct file *file, if (!send_tomtou && !send_writers) return; - *pathname = ima_d_path(&file->f_path, pathbuf); + *pathname = ima_d_path(&file->f_path, pathbuf, filename); if (send_tomtou) ima_add_violation(file, *pathname, iint, @@ -161,6 +162,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size, struct integrity_iint_cache *iint = NULL; struct ima_template_desc *template_desc; char *pathbuf = NULL; + char filename[NAME_MAX]; const char *pathname = NULL; int rc = -ENOMEM, action, must_appraise; int pcr = CONFIG_IMA_MEASURE_PCR_IDX; @@ -239,8 +241,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size, goto out_digsig; } - if (!pathname) /* ima_rdwr_violation possibly pre-fetched */ - pathname = ima_d_path(&file->f_path, &pathbuf); + if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ + pathname = ima_d_path(&file->f_path, &pathbuf, filename); if (action & IMA_MEASURE) ima_store_measurement(iint, file, pathname,