Skip to content

Commit bc15ed6

Browse files
author
Mimi Zohar
committed
ima: fix ima_d_path() possible race with rename
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@zeniv.linux.org.uk> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Cc: stable@vger.kernel.org
1 parent 710584b commit bc15ed6

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

security/integrity/ima/ima.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ int ima_store_template(struct ima_template_entry *entry, int violation,
204204
struct inode *inode,
205205
const unsigned char *filename, int pcr);
206206
void ima_free_template_entry(struct ima_template_entry *entry);
207-
const char *ima_d_path(const struct path *path, char **pathbuf);
207+
const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
208208

209209
/* IMA policy related functions */
210210
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,

security/integrity/ima/ima_api.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,17 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
318318
iint->flags |= IMA_AUDITED;
319319
}
320320

321-
const char *ima_d_path(const struct path *path, char **pathbuf)
321+
/*
322+
* ima_d_path - return a pointer to the full pathname
323+
*
324+
* Attempt to return a pointer to the full pathname for use in the
325+
* IMA measurement list, IMA audit records, and auditing logs.
326+
*
327+
* On failure, return a pointer to a copy of the filename, not dname.
328+
* Returning a pointer to dname, could result in using the pointer
329+
* after the memory has been freed.
330+
*/
331+
const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
322332
{
323333
char *pathname = NULL;
324334

@@ -331,5 +341,11 @@ const char *ima_d_path(const struct path *path, char **pathbuf)
331341
pathname = NULL;
332342
}
333343
}
334-
return pathname ?: (const char *)path->dentry->d_name.name;
344+
345+
if (!pathname) {
346+
strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX);
347+
pathname = namebuf;
348+
}
349+
350+
return pathname;
335351
}

security/integrity/ima/ima_main.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static void ima_rdwr_violation_check(struct file *file,
8383
const char **pathname)
8484
{
8585
struct inode *inode = file_inode(file);
86+
char filename[NAME_MAX];
8687
fmode_t mode = file->f_mode;
8788
bool send_tomtou = false, send_writers = false;
8889

@@ -102,7 +103,7 @@ static void ima_rdwr_violation_check(struct file *file,
102103
if (!send_tomtou && !send_writers)
103104
return;
104105

105-
*pathname = ima_d_path(&file->f_path, pathbuf);
106+
*pathname = ima_d_path(&file->f_path, pathbuf, filename);
106107

107108
if (send_tomtou)
108109
ima_add_violation(file, *pathname, iint,
@@ -161,6 +162,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
161162
struct integrity_iint_cache *iint = NULL;
162163
struct ima_template_desc *template_desc;
163164
char *pathbuf = NULL;
165+
char filename[NAME_MAX];
164166
const char *pathname = NULL;
165167
int rc = -ENOMEM, action, must_appraise;
166168
int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
@@ -239,8 +241,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
239241
goto out_digsig;
240242
}
241243

242-
if (!pathname) /* ima_rdwr_violation possibly pre-fetched */
243-
pathname = ima_d_path(&file->f_path, &pathbuf);
244+
if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */
245+
pathname = ima_d_path(&file->f_path, &pathbuf, filename);
244246

245247
if (action & IMA_MEASURE)
246248
ima_store_measurement(iint, file, pathname,

0 commit comments

Comments
 (0)