From: Greg Kroah-Hartman Date: Wed, 19 Jun 2024 12:15:08 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.1.95~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f149b47078e064043886a5a7cbb6114586353019;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch ima-fix-use-after-free-on-a-dentry-s-dname.name.patch --- diff --git a/queue-6.6/greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch b/queue-6.6/greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch new file mode 100644 index 00000000000..9dc97e274e3 --- /dev/null +++ b/queue-6.6/greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch @@ -0,0 +1,52 @@ +From 5c9c5d7f26acc2c669c1dcf57d1bb43ee99220ce Mon Sep 17 00:00:00 2001 +From: Sicong Huang +Date: Tue, 16 Apr 2024 16:03:13 +0800 +Subject: greybus: Fix use-after-free bug in gb_interface_release due to race condition. + +From: Sicong Huang + +commit 5c9c5d7f26acc2c669c1dcf57d1bb43ee99220ce upstream. + +In gb_interface_create, &intf->mode_switch_completion is bound with +gb_interface_mode_switch_work. Then it will be started by +gb_interface_request_mode_switch. Here is the relevant code. +if (!queue_work(system_long_wq, &intf->mode_switch_work)) { + ... +} + +If we call gb_interface_release to make cleanup, there may be an +unfinished work. This function will call kfree to free the object +"intf". However, if gb_interface_mode_switch_work is scheduled to +run after kfree, it may cause use-after-free error as +gb_interface_mode_switch_work will use the object "intf". +The possible execution flow that may lead to the issue is as follows: + +CPU0 CPU1 + + | gb_interface_create + | gb_interface_request_mode_switch +gb_interface_release | +kfree(intf) (free) | + | gb_interface_mode_switch_work + | mutex_lock(&intf->mutex) (use) + +Fix it by canceling the work before kfree. + +Signed-off-by: Sicong Huang +Link: https://lore.kernel.org/r/20240416080313.92306-1-congei42@163.com +Cc: Ronnie Sahlberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/greybus/interface.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/greybus/interface.c ++++ b/drivers/greybus/interface.c +@@ -694,6 +694,7 @@ static void gb_interface_release(struct + + trace_gb_interface_release(intf); + ++ cancel_work_sync(&intf->mode_switch_work); + kfree(intf); + } + diff --git a/queue-6.6/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch b/queue-6.6/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch new file mode 100644 index 00000000000..013babb6c4a --- /dev/null +++ b/queue-6.6/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch @@ -0,0 +1,114 @@ +From be84f32bb2c981ca670922e047cdde1488b233de Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Fri, 22 Mar 2024 10:03:12 -0400 +Subject: ima: Fix use-after-free on a dentry's dname.name + +From: Stefan Berger + +commit be84f32bb2c981ca670922e047cdde1488b233de 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 +Signed-off-by: Stefan Berger +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman +--- + security/integrity/ima/ima_api.c | 16 ++++++++++++---- + security/integrity/ima/ima_template_lib.c | 17 ++++++++++++++--- + 2 files changed, 26 insertions(+), 7 deletions(-) + +--- a/security/integrity/ima/ima_api.c ++++ b/security/integrity/ima/ima_api.c +@@ -244,8 +244,8 @@ int ima_collect_measurement(struct integ + 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; +@@ -316,9 +316,13 @@ out: + 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; + } +@@ -431,6 +435,7 @@ out: + */ + const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf) + { ++ struct name_snapshot filename; + char *pathname = NULL; + + *pathbuf = __getname(); +@@ -444,7 +449,10 @@ const char *ima_d_path(const struct path + } + + 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; + } + +--- 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(str + 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(str + } + + 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(str + */ + 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; + } + + /* diff --git a/queue-6.6/series b/queue-6.6/series index db18c07cefa..c7a47b2a3c5 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -252,3 +252,5 @@ selftests-net-lib-update-busywait-timeout-value.patch selftests-net-lib-no-need-to-record-ns-name-if-it-already-exist.patch selftests-net-lib-support-errexit-with-busywait.patch selftests-net-lib-avoid-error-removing-empty-netns-name.patch +greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch +ima-fix-use-after-free-on-a-dentry-s-dname.name.patch