[PATCH 2/9] w1: remove the master's files before taking its locks

From: Greg Kroah-Hartman

Date: Tue Oct 27 2026 - 12:12:25 EST


From: Josef Bacik <josef@xxxxxxxxxxxxxx>

__w1_remove_master_device() calls w1_destroy_master_attributes() with
both the mutex of the master and list_mutex held. Removing the files
waits for the callbacks which are running, and nearly all of them take
one of these two locks:

__w1_remove_master_device() read() of .../w1_master_slaves
mutex_lock(&dev->mutex) kernfs active reference
mutex_lock(&dev->list_mutex) w1_master_attribute_show_slaves()
w1_destroy_master_attributes() mutex_lock(&md->list_mutex)
sysfs_remove_group() waits
waits for the reference

The files are readable for everybody, and a bus master goes away when, for
instance, a DS2490 USB adapter is unplugged.

Remove the files first, before the locks are taken. That has to be done
before the slaves are detached and not afterwards: as long as the files
exist, a write to w1_master_add could attach a new slave behind the back
of this function, which would then wait for the reference count of the
master for ever. And it is done before the thread is stopped, because a
write to w1_master_search wakes the thread up.

Fixes: c30c9b15187e ("W1: fix deadlocks and remove w1_control_thread")
Cc: stable <stable@xxxxxxxxxx>
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/w1/w1_int.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 19a0ea28e9f3..3fcc9ee56727 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -176,6 +176,13 @@ void __w1_remove_master_device(struct w1_master *dev)
mutex_unlock(&w1_mlock);

set_bit(W1_ABORT_SEARCH, &dev->flags);
+
+ /*
+ * This waits for the callbacks, which take the locks below. One of
+ * them wakes the thread up.
+ */
+ w1_destroy_master_attributes(dev);
+
kthread_stop(dev->thread);

mutex_lock(&dev->mutex);
@@ -185,7 +192,6 @@ void __w1_remove_master_device(struct w1_master *dev)
w1_slave_detach(sl);
mutex_lock(&dev->list_mutex);
}
- w1_destroy_master_attributes(dev);
mutex_unlock(&dev->list_mutex);
mutex_unlock(&dev->mutex);
atomic_dec(&dev->refcnt);

--
2.56.0