Skip to contentSkip to conversation

Patch "driver core: enforce device_lock for driver_match_device()" has been added to the 6.1-stable tree

DISCUSSION Gui-Dong Han 2 participants 2 messages Mar 9 1 message not in the archive Stable branch

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw
Quoted 8 lines · Sasha Levin

This is a note to let you know that I've just added the patch titled

driver core: enforce device_lock for driver_match_device()

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

Quoted 6 lines

The filename of the patch is:
driver-core-enforce-device_lock-for-driver_match_dev.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Hi Sasha,

Please drop this patch from 6.1 and all other stable queues.

This commit was reverted upstream. Enforcing the device_lock here introduced side effects [1]. We are currently developing a new approach to fix the original issue [2].

Thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9de68394a615
[2] https://lore.kernel.org/driver-core/[email protected]/

Quoted 92 lines

commit 43fcab97a217ccdc2da2d8644f88398dc061e1e9

Author: Gui-Dong Han <[email protected]>
Date:   Wed Jan 14 00:28:43 2026 +0800

driver core: enforce device_lock for driver_match_device()

[ Upstream commit dc23806a7c47ec5f1293aba407fb69519f976ee0 ]

Currently, driver_match_device() is called from three sites. One site (__device_attach_driver) holds device_lock(dev), but the other two (bind_store and __driver_attach) do not. This inconsistency means that bus match() callbacks are not guaranteed to be called with the lock held.

Fix this by introducing driver_match_device_locked(), which guarantees holding the device lock using a scoped guard. Replace the unlocked calls in bind_store() and __driver_attach() with this new helper. Also add a lock assertion to driver_match_device() to enforce this guarantee.

This consistency also fixes a known race condition. The driver_override implementation relies on the device_lock, so the missing lock led to the use-after-free (UAF) reported in Bugzilla for buses using this field.

Stress testing the two newly locked paths for 24 hours with CONFIG_PROVE_LOCKING and CONFIG_LOCKDEP enabled showed no UAF recurrence and no lockdep warnings.

drivers/base/base.h +9 -0
index 2a6cf004dedc3..4e06810efe3e0 100644
@@ -144,10 +144,19 @@ extern void device_set_deferred_probe_reason(const struct device *dev,
 static inline int driver_match_device(struct device_driver *drv,
                                      struct device *dev)
 {
+       device_lock_assert(dev);
+
        return drv->bus->match ? drv->bus->match(dev, drv) : 1;
 }
 extern bool driver_allows_async_probing(struct device_driver *drv);
 
+static inline int driver_match_device_locked(const struct device_driver *drv,
+                                            struct device *dev)
+{
+       guard(device)(dev);
+       return driver_match_device(drv, dev);
+}
+
 static inline void dev_sync_state(struct device *dev)
 {
        if (dev->bus->sync_state)
drivers/base/bus.c +1 -1
index 941532ddfdc68..78a64f2784d05 100644
@@ -212,7 +212,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
        int err = -ENODEV;
 
        dev = bus_find_device_by_name(bus, NULL, buf);
-       if (dev && driver_match_device(drv, dev)) {
+       if (dev && driver_match_device_locked(drv, dev)) {
                err = device_driver_attach(drv, dev);
                if (!err) {
                        /* success */
drivers/base/dd.c +1 -1
index 6ad1b6eae65d6..02c846be7b174 100644
@@ -1175,7 +1175,7 @@ static int __driver_attach(struct device *dev, void *data)
         * is an error.
         */
 
-       ret = driver_match_device(drv, dev);
+       ret = driver_match_device_locked(drv, dev);
        if (ret == 0) {
                /* no match */
                return 0;
#2 lore raw
Quoted 20 lines · Gui-Dong Han
Quoted 8 lines · Sasha Levin

This is a note to let you know that I've just added the patch titled

driver core: enforce device_lock for driver_match_device()

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

Quoted 6 lines

The filename of the patch is:
driver-core-enforce-device_lock-for-driver_match_dev.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Hi Sasha,

Please drop this patch from 6.1 and all other stable queues.

Quoted 8 lines

This commit was reverted upstream. Enforcing the device_lock here introduced side effects [1]. We are currently developing a new approach to fix the original issue [2].

Thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9de68394a615
[2] https://lore.kernel.org/driver-core/[email protected]/

Now dropped from everywhere, thanks for catching this again.

greg k-h