--- /dev/null
+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
+@@ -693,6 +693,7 @@ static void gb_interface_release(struct
+
+ trace_gb_interface_release(intf);
+
++ cancel_work_sync(&intf->mode_switch_work);
+ kfree(intf);
+ }
+
--- /dev/null
+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
+@@ -245,8 +245,8 @@ int ima_collect_measurement(struct ima_i
+ 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 @@ 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;
+ }
+@@ -432,6 +436,7 @@ out:
+ */
+ 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
+ }
+
+ 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;
+ }
+
+ /*