FAILED: patch "[PATCH] ima: Fix use-after-free on a dentry's dname.name" failed to apply to 5.15-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x be84f32bb2c981ca6709
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024061919-angelic-granny-6472@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From be84f32bb2c981ca670922e047cdde1488b233de Mon Sep 17 00:00:00 2001
From: Stefan Berger <[email protected]>
Date: Fri, 22 Mar 2024 10:03:12 -0400
Subject: [PATCH] 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.
security/integrity/ima/ima_api.c +12 -4
@@ -245,8 +245,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,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 ima_max_digest_data hash; +struct name_snapshot filename;struct kstat stat;int result =0 ;int length;
@@ -317,9 +317,13 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,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; }
@@ -432,6 +436,7 @@ void ima_audit_measurement(struct ima_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 ();
@@ -445,7 +450,10 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf) }if (!pathname) { -strscpy (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; }
security/integrity/ima/ima_template_lib.c +14 -3
@@ -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; }/*
PATCH 1/1 ima: Fix use-after-free on a dentry's dname.name
From: Stefan Berger <[email protected]>
[ Upstream commit be84f32bb2c981ca670922e047cdde1488b233de ]
->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.
--- security/integrity/ima/ima_api.c | 16 ++++++++++++---- security/integrity/ima/ima_template_lib.c | 17 ++++++++++++++--- 2 files changed, 26 insertions(+), 7 deletions(-)
security/integrity/ima/ima_api.c +12 -4
@@ -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; }
security/integrity/ima/ima_template_lib.c +14 -3
@@ -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; }/*
Signature · 1 line
2.25.1
Sasha Levin
maintainerRe: [PATCH 5.15.y] ima: Fix use-after-free on a dentry's dname.name
[ Sasha's backport helper bot ]
Hi,
The upstream commit SHA1 provided is correct: be84f32bb2c981ca670922e047cdde1488b233de
WARNING: Author mismatch between patch and upstream commit:
Backport author: [email protected]
Commit author: Stefan Berger <[email protected]>
Status in newer kernel trees:
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: dd431c3ac1fc) 6.1.y | Present (different SHA1: 7fb374981e31) 5.15.y | Not found
Note: The patch differs from the upstream commit:
---
1: be84f32bb2c98 ! 1: 033c0527f3846 ima: Fix use-after-free on a dentry's dname.name
@@ Metadata
## Commit message ##
ima: Fix use-after-free on a dentry's dname.name
+ [ Upstream commit be84f32bb2c981ca670922e047cdde1488b233de ]
+
->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,
@@ Commit message
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
+ Signed-off-by: Sasha Levin <[email protected]>
+ Signed-off-by: Libo Chen <[email protected]>
## security/integrity/ima/ima_api.c ##
-@@ security/integrity/ima/ima_api.c: int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
+@@ security/integrity/ima/ima_api.c: 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 ima_max_digest_data hash;
+ struct name_snapshot filename;
- struct kstat stat;
int result = 0;
int length;
-@@ security/integrity/ima/ima_api.c: int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
+ void *tmpbuf;
+@@ security/integrity/ima/ima_api.c: int ima_collect_measurement(struct integrity_iint_cache *iint,
if (file->f_flags & O_DIRECT)
audit_cause = "failed(directio)";
@@ security/integrity/ima/ima_api.c: int ima_collect_measurement(struct ima_iint_ca
}
return result;
}
-@@ security/integrity/ima/ima_api.c: void ima_audit_measurement(struct ima_iint_cache *iint,
+@@ security/integrity/ima/ima_api.c: void ima_audit_measurement(struct integrity_iint_cache *iint,
*/
const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
{
@@ security/integrity/ima/ima_api.c: const char *ima_d_path(const struct path *path
}
if (!pathname) {
-- strscpy(namebuf, path->dentry->d_name.name, NAME_MAX);
+- 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);---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |
Greg KH
maintainerRe: [PATCH 5.15.y] ima: Fix use-after-free on a dentry's dname.name
In reply to [email protected]Quoted 3 lines · On Tue, Dec 10, 2024 at 10:02:52AM +0800, [email protected] wrote:
From: Stefan Berger <[email protected]>
[ Upstream commit
be84f32bb2c981ca670922e047cdde1488b233de]
Please cc: all relevant people on backports.