mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
ima: Fix use-after-free on a dentry's dname.name
commit be84f32bb2
upstream.
->d_name.name can change on rename and the earlier value can be freed;
there are conditions sufficient to stabilize it (->d_lock on dentry,
->d_lock on its parent, ->i_rwsem exclusive on the parent's inode,
rename_lock), but none of those are met at any of the sites. Take a stable
snapshot of the name instead.
Link: https://lore.kernel.org/all/20240202182732.GE2087318@ZenIV/
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Libo Chen <libo.chen.cn@windriver.com>
This commit is contained in:
parent
801d64177f
commit
0b31e28fbd
@ -217,7 +217,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
const char *audit_cause = "failed";
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *real_inode = d_real_inode(file_dentry(file));
|
||||
const char *filename = file->f_path.dentry->d_name.name;
|
||||
struct name_snapshot filename;
|
||||
int result = 0;
|
||||
int length;
|
||||
void *tmpbuf;
|
||||
@ -280,9 +280,13 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
if (file->f_flags & O_DIRECT)
|
||||
audit_cause = "failed(directio)";
|
||||
|
||||
take_dentry_name_snapshot(&filename, file->f_path.dentry);
|
||||
|
||||
integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
|
||||
filename, "collect_data", audit_cause,
|
||||
result, 0);
|
||||
filename.name.name, "collect_data",
|
||||
audit_cause, result, 0);
|
||||
|
||||
release_dentry_name_snapshot(&filename);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -395,6 +399,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
|
||||
*/
|
||||
const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
|
||||
{
|
||||
struct name_snapshot filename;
|
||||
char *pathname = NULL;
|
||||
|
||||
*pathbuf = __getname();
|
||||
@ -408,7 +413,10 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
|
||||
}
|
||||
|
||||
if (!pathname) {
|
||||
strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX);
|
||||
take_dentry_name_snapshot(&filename, path->dentry);
|
||||
strscpy(namebuf, filename.name.name, NAME_MAX);
|
||||
release_dentry_name_snapshot(&filename);
|
||||
|
||||
pathname = namebuf;
|
||||
}
|
||||
|
||||
|
@ -426,7 +426,10 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
|
||||
bool size_limit)
|
||||
{
|
||||
const char *cur_filename = NULL;
|
||||
struct name_snapshot filename;
|
||||
u32 cur_filename_len = 0;
|
||||
bool snapshot = false;
|
||||
int ret;
|
||||
|
||||
BUG_ON(event_data->filename == NULL && event_data->file == NULL);
|
||||
|
||||
@ -439,7 +442,10 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
|
||||
}
|
||||
|
||||
if (event_data->file) {
|
||||
cur_filename = event_data->file->f_path.dentry->d_name.name;
|
||||
take_dentry_name_snapshot(&filename,
|
||||
event_data->file->f_path.dentry);
|
||||
snapshot = true;
|
||||
cur_filename = filename.name.name;
|
||||
cur_filename_len = strlen(cur_filename);
|
||||
} else
|
||||
/*
|
||||
@ -448,8 +454,13 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
|
||||
*/
|
||||
cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
|
||||
out:
|
||||
return ima_write_template_field_data(cur_filename, cur_filename_len,
|
||||
DATA_FMT_STRING, field_data);
|
||||
ret = ima_write_template_field_data(cur_filename, cur_filename_len,
|
||||
DATA_FMT_STRING, field_data);
|
||||
|
||||
if (snapshot)
|
||||
release_dentry_name_snapshot(&filename);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user