]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.14
authorSasha Levin <sashal@kernel.org>
Sat, 26 Feb 2022 02:59:34 +0000 (21:59 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 26 Feb 2022 02:59:34 +0000 (21:59 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch [new file with mode: 0644]
queue-4.14/rdma-ib_srp-fix-a-deadlock.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch b/queue-4.14/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch
new file mode 100644 (file)
index 0000000..35fe021
--- /dev/null
@@ -0,0 +1,98 @@
+From 422fd2a7d7857c355a76ec3f840dd7a15bd63b25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 15:10:30 +0800
+Subject: configfs: fix a race in configfs_{,un}register_subsystem()
+
+From: ChenXiaoSong <chenxiaosong2@huawei.com>
+
+[ 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 <chenxiaosong2@huawei.com>
+Signed-off-by: Laibin Qiu <qiulaibin@huawei.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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.14/rdma-ib_srp-fix-a-deadlock.patch b/queue-4.14/rdma-ib_srp-fix-a-deadlock.patch
new file mode 100644 (file)
index 0000000..09162cc
--- /dev/null
@@ -0,0 +1,45 @@
+From 929b4cc79b770b8372fd0b371e37ae46b84eea47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 13:05:11 -0800
+Subject: RDMA/ib_srp: Fix a deadlock
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ 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 <bvanassche@acm.org>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 9f7287f45d06f..63358c4c8e57c 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -3683,9 +3683,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
+
index 12cf6a6e3519d38c2efbfc1122708cf6888fd2e6..c06f8f20250fc5797f4ff6344f504d0be2f7a0ab 100644 (file)
@@ -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