]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jun 2024 12:15:08 +0000 (14:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jun 2024 12:15:08 +0000 (14:15 +0200)
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

queue-6.6/greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.patch [new file with mode: 0644]
queue-6.6/ima-fix-use-after-free-on-a-dentry-s-dname.name.patch [new file with mode: 0644]
queue-6.6/series

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 (file)
index 0000000..9dc97e2
--- /dev/null
@@ -0,0 +1,52 @@
+From 5c9c5d7f26acc2c669c1dcf57d1bb43ee99220ce Mon Sep 17 00:00:00 2001
+From: Sicong Huang <congei42@163.com>
+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 <congei42@163.com>
+
+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 <congei42@163.com>
+Link: https://lore.kernel.org/r/20240416080313.92306-1-congei42@163.com
+Cc: Ronnie Sahlberg <rsahlberg@ciq.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..013babb
--- /dev/null
@@ -0,0 +1,114 @@
+From be84f32bb2c981ca670922e047cdde1488b233de Mon Sep 17 00:00:00 2001
+From: Stefan Berger <stefanb@linux.ibm.com>
+Date: Fri, 22 Mar 2024 10:03:12 -0400
+Subject: ima: Fix use-after-free on a dentry's dname.name
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+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 <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>
+---
+ 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;
+ }
+ /*
index db18c07cefaf2a5270a846dd51fb58eb873727e8..c7a47b2a3c5ab3bb24381081cb23b8a4b4f05014 100644 (file)
@@ -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