From: Sasha Levin Date: Sat, 26 Feb 2022 02:59:34 +0000 (-0500) Subject: Fixes for 4.9 X-Git-Tag: v4.9.304~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e40c1a711890c2916c0265c2a1571a0514f08a5;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch b/queue-4.9/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch new file mode 100644 index 00000000000..cca27831694 --- /dev/null +++ b/queue-4.9/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch @@ -0,0 +1,98 @@ +From 3ed953f1110242ccf5098bb7b497795131ec2a10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 15:10:30 +0800 +Subject: configfs: fix a race in configfs_{,un}register_subsystem() + +From: ChenXiaoSong + +[ Upstream commit 84ec758fb2daa236026506868c8796b0500c047d ] + +When configfs_register_subsystem() or configfs_unregister_subsystem() +is executing link_group() or unlink_group(), +it is possible that two processes add or delete list concurrently. +Some unfortunate interleavings of them can cause kernel panic. + +One of cases is: +A --> B --> C --> D +A <-- B <-- C <-- D + + delete list_head *B | delete list_head *C +--------------------------------|----------------------------------- +configfs_unregister_subsystem | configfs_unregister_subsystem + unlink_group | unlink_group + unlink_obj | unlink_obj + list_del_init | list_del_init + __list_del_entry | __list_del_entry + __list_del | __list_del + // next == C | + next->prev = prev | + | next->prev = prev + prev->next = next | + | // prev == B + | prev->next = next + +Fix this by adding mutex when calling link_group() or unlink_group(), +but parent configfs_subsystem is NULL when config_item is root. +So I create a mutex configfs_subsystem_mutex. + +Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem") +Signed-off-by: ChenXiaoSong +Signed-off-by: Laibin Qiu +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + fs/configfs/dir.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index c875f246cb0e9..ccb49caed502c 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -50,6 +50,14 @@ DECLARE_RWSEM(configfs_rename_sem); + */ + DEFINE_SPINLOCK(configfs_dirent_lock); + ++/* ++ * All of link_obj/unlink_obj/link_group/unlink_group require that ++ * subsys->su_mutex is held. ++ * But parent configfs_subsystem is NULL when config_item is root. ++ * Use this mutex when config_item is root. ++ */ ++static DEFINE_MUTEX(configfs_subsystem_mutex); ++ + static void configfs_d_iput(struct dentry * dentry, + struct inode * inode) + { +@@ -1937,7 +1945,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + group->cg_item.ci_name = group->cg_item.ci_namebuf; + + sd = root->d_fsdata; ++ mutex_lock(&configfs_subsystem_mutex); + link_group(to_config_group(sd->s_element), group); ++ mutex_unlock(&configfs_subsystem_mutex); + + inode_lock_nested(d_inode(root), I_MUTEX_PARENT); + +@@ -1962,7 +1972,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + inode_unlock(d_inode(root)); + + if (err) { ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + put_fragment(frag); +@@ -2008,7 +2020,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) + + dput(dentry); + ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + +-- +2.34.1 + diff --git a/queue-4.9/rdma-ib_srp-fix-a-deadlock.patch b/queue-4.9/rdma-ib_srp-fix-a-deadlock.patch new file mode 100644 index 00000000000..435bc017da8 --- /dev/null +++ b/queue-4.9/rdma-ib_srp-fix-a-deadlock.patch @@ -0,0 +1,45 @@ +From a0c4a7b02ff52c0b45ce94b73313fd8f5411470a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 13:05:11 -0800 +Subject: RDMA/ib_srp: Fix a deadlock + +From: Bart Van Assche + +[ Upstream commit 081bdc9fe05bb23248f5effb6f811da3da4b8252 ] + +Remove the flush_workqueue(system_long_wq) call since flushing +system_long_wq is deadlock-prone and since that call is redundant with a +preceding cancel_work_sync() + +Link: https://lore.kernel.org/r/20220215210511.28303-3-bvanassche@acm.org +Fixes: ef6c49d87c34 ("IB/srp: Eliminate state SRP_TARGET_DEAD") +Reported-by: syzbot+831661966588c802aae9@syzkaller.appspotmail.com +Signed-off-by: Bart Van Assche +Reviewed-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/srp/ib_srp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index af68be201c299..67b993f4ec91a 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -3646,9 +3646,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data) + spin_unlock(&host->target_lock); + + /* +- * Wait for tl_err and target port removal tasks. ++ * srp_queue_remove_work() queues a call to ++ * srp_remove_target(). The latter function cancels ++ * target->tl_err_work so waiting for the remove works to ++ * finish is sufficient. + */ +- flush_workqueue(system_long_wq); + flush_workqueue(srp_remove_wq); + + kfree(host); +-- +2.34.1 + diff --git a/queue-4.9/series b/queue-4.9/series index ff89405ffb9..e1fdf33a773 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -11,3 +11,5 @@ gso-do-not-skip-outer-ip-header-in-case-of-ipip-and-net_failover.patch openvswitch-fix-setting-ipv6-fields-causing-hw-csum-failure.patch drm-edid-always-set-rgb444.patch net-mlx5e-fix-wrong-return-value-on-ioctl-eeprom-query-failure.patch +configfs-fix-a-race-in-configfs_-un-register_subsyst.patch +rdma-ib_srp-fix-a-deadlock.patch