summaryrefslogtreecommitdiff
path: root/security/integrity/ima/ima_template_lib.c
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.ibm.com>2024-03-22 10:03:12 -0400
committerMimi Zohar <zohar@linux.ibm.com>2024-04-08 07:55:47 -0400
commitbe84f32bb2c981ca670922e047cdde1488b233de (patch)
treea3c135a23ab2e801c0f2ab977e0a77d2122cdb13 /security/integrity/ima/ima_template_lib.c
parentfec50db7033ea478773b159e0e2efb135270e3b7 (diff)
ima: Fix use-after-free on a dentry's dname.name
->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>
Diffstat (limited to 'security/integrity/ima/ima_template_lib.c')
-rw-r--r--security/integrity/ima/ima_template_lib.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 6cd0add524cd..3b2cb8f1002e 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -483,7 +483,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);
@@ -496,7 +499,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
/*
@@ -505,8 +511,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;
}
/*