lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 10 Mar 2017 10:08:04 +0100
From:   Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To:     linux-kernel@...r.kernel.org
Cc:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        stable@...r.kernel.org, Al Viro <viro@...iv.linux.org.uk>,
        Mimi Zohar <zohar@...ux.vnet.ibm.com>
Subject: [PATCH 4.9 051/153] ima: fix ima_d_path() possible race with rename

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mimi Zohar <zohar@...ux.vnet.ibm.com>

commit bc15ed663e7e53ee4dc3e60f8d09c93a0528c694 upstream.

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.

Intead of returning a pointer to dname on failure, this patch returns
a pointer to a copy of the filename.

Reported-by: Al Viro <viro@...iv.linux.org.uk>
Signed-off-by: Mimi Zohar <zohar@...ux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>

---
 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(-)

--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -173,7 +173,7 @@ int ima_store_template(struct ima_templa
 		       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,
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -318,7 +318,17 @@ void ima_audit_measurement(struct integr
 	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
 			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;
 }
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -83,6 +83,7 @@ static void ima_rdwr_violation_check(str
 				     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(str
 	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 fi
 	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 fi
 		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,


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ