* [PATCH v2 1/3] driver core: provide a test-and-clear device flag accessor
2026-10-23 10:14 [PATCH v2 0/3] driver core: fix unbalanced reference counting for software nodes Bartosz Golaszewski
@ 2026-10-23 10:14 ` Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 2/3] driver core: provide new device flag - DEV_FLAG_SWNODE_NOTIFIER Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 3/3] software node: fix unbalanced reference counting Bartosz Golaszewski
2 siblings, 0 replies; 4+ messages in thread
From: Bartosz Golaszewski @ 2026-10-23 10:14 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Eduardo Ruiz Duarte, Bartosz Golaszewski
Cc: driver-core, linux-kernel, Rafael J. Wysocki, linux-acpi,
Bartosz Golaszewski
Extend the device flag accessors with a test-and-clear operation.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/device.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/linux/device.h b/include/linux/device.h
index 429e39f647cf907d2a9868878d1f89526345c3cd..f31fd62dca9a89c1c9ad565b1cd673b71b740faf 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -822,6 +822,10 @@ static inline void dev_assign_##accessor_name(struct device *dev, bool value) \
static inline bool dev_test_and_set_##accessor_name(struct device *dev) \
{ \
return test_and_set_bit(flag_name, dev->flags); \
+} \
+static inline bool dev_test_and_clear_##accessor_name(struct device *dev) \
+{ \
+ return test_and_clear_bit(flag_name, dev->flags); \
}
__create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE);
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v2 2/3] driver core: provide new device flag - DEV_FLAG_SWNODE_NOTIFIER
2026-10-23 10:14 [PATCH v2 0/3] driver core: fix unbalanced reference counting for software nodes Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 1/3] driver core: provide a test-and-clear device flag accessor Bartosz Golaszewski
@ 2026-10-23 10:14 ` Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 3/3] software node: fix unbalanced reference counting Bartosz Golaszewski
2 siblings, 0 replies; 4+ messages in thread
From: Bartosz Golaszewski @ 2026-10-23 10:14 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Eduardo Ruiz Duarte, Bartosz Golaszewski
Cc: driver-core, linux-kernel, Rafael J. Wysocki, linux-acpi,
Bartosz Golaszewski
Extend the set of device flags with one that indicates to driver core
that this device was passed as argument to software_node_notify() and
took a reference to this device's software node.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/device.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/linux/device.h b/include/linux/device.h
index f31fd62dca9a89c1c9ad565b1cd673b71b740faf..6b082c638d451deef62a607095335e807b0841e2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -604,6 +604,10 @@ struct device_physical_location {
* ancestor device.
* @DEV_FLAG_OFFLINE_DISABLED: If set, the device is permanently online.
* @DEV_FLAG_OFFLINE: Set after successful invocation of bus type's .offline().
+ * @DEV_FLAG_SWNODE_NOTIFIED: Set if software_node_notify() was called for this
+ * device and took a reference to the device's software node.
+ * Indicates to software_node_notify_remove() that it should drop
+ * the reference.
* @DEV_FLAG_COUNT: Number of defined struct_device_flags.
*/
enum struct_device_flags {
@@ -617,6 +621,7 @@ enum struct_device_flags {
DEV_FLAG_OF_NODE_REUSED = 7,
DEV_FLAG_OFFLINE_DISABLED = 8,
DEV_FLAG_OFFLINE = 9,
+ DEV_FLAG_SWNODE_NOTIFIED = 10,
DEV_FLAG_COUNT
};
@@ -838,6 +843,7 @@ __create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT);
__create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED);
__create_dev_flag_accessors(offline_disabled, DEV_FLAG_OFFLINE_DISABLED);
__create_dev_flag_accessors(offline, DEV_FLAG_OFFLINE);
+__create_dev_flag_accessors(swnode_notified, DEV_FLAG_SWNODE_NOTIFIED);
#undef __create_dev_flag_accessors
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v2 3/3] software node: fix unbalanced reference counting
2026-10-23 10:14 [PATCH v2 0/3] driver core: fix unbalanced reference counting for software nodes Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 1/3] driver core: provide a test-and-clear device flag accessor Bartosz Golaszewski
2026-10-23 10:14 ` [PATCH v2 2/3] driver core: provide new device flag - DEV_FLAG_SWNODE_NOTIFIER Bartosz Golaszewski
@ 2026-10-23 10:14 ` Bartosz Golaszewski
2 siblings, 0 replies; 4+ messages in thread
From: Bartosz Golaszewski @ 2026-10-23 10:14 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Eduardo Ruiz Duarte, Bartosz Golaszewski
Cc: driver-core, linux-kernel, Rafael J. Wysocki, linux-acpi,
Bartosz Golaszewski, stable
software_node_notify() takes a reference to the device's software node.
software_node_notify_remove() drops it unconditionally. A software node
attached with set_secondary_fwnode() after the device was registered
never gets it reference count increased but it gets decreased in
software_node_notify_remove() all the same causing an underflow and a
use-after-free. Use the new device flag to mark a device that needs the
reference to its software node decreased on device_del() and do it
conditionally in software_node_notify_remove().
Cc: stable@vger.kernel.org
Fixes: 384f5a857bae ("software nodes: Split software_node_notify()")
Reported-by: Eduardo Ruiz Duarte <toorandom@gmail.com>
Closes: https://lore.kernel.org/all/20261011131518.48838-1-toorandom@gmail.com/
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/base/swnode.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 84a77ffa3dc4bbcca62bbe67c3390693500b01ea..9207d7f96f20f8cfaff2a4eb8915609c499cce24 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -1176,6 +1176,8 @@ void software_node_notify(struct device *dev)
swnode->fwnode.dev = dev;
swnode_get(swnode);
+ dev_set_swnode_notified(dev);
+
ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
if (ret)
return;
@@ -1206,7 +1208,8 @@ void software_node_notify_remove(struct device *dev)
if (!device_match_fwnode(dev, &swnode->fwnode) && swnode->fwnode.dev == dev)
swnode->fwnode.dev = NULL;
- swnode_put(swnode);
+ if (dev_test_and_clear_swnode_notified(dev))
+ swnode_put(swnode);
if (swnode->managed) {
set_secondary_fwnode(dev, NULL);
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread