From 9dcfc8e6bae658288fa6f112efc18246285f0f27 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Jun 2021 13:31:51 +0300 Subject: [PATCH] software node: Handle software node injection to an existing device properly The function software_node_notify(), which creates and removes the symlinks between the software node and the device, must be called conditionally. In normal case software_node_notify() is called automatically when the device that the software node is assigned to is registered, and only in the special cases where the software node has to be added to an already existing device it needs to be called separately. This fixes NULL pointer dereference that happenes if device_remove_software_node() is called with device that was never registered. Fixes: b622b24519f5 ("software node: Allow node addition to already existing device") Reported-by: Dominik Brodowski Cc: Andy Shevchenko Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 3cc11b813f28c..042eef31b182a 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -1045,7 +1045,16 @@ int device_add_software_node(struct device *dev, const struct software_node *nod } set_secondary_fwnode(dev, &swnode->fwnode); - software_node_notify(dev, KOBJ_ADD); + + /* + * Software nodes are also allowed to be added to already existing + * devices. If the device has been fully registered by the time this + * function is called, software_node_notify() must be called separately + * so that the symlinks get created and the reference count of the node + * is kept in balance. + */ + if (device_is_registered(dev)) + software_node_notify(dev, KOBJ_ADD); return 0; } @@ -1065,7 +1074,8 @@ void device_remove_software_node(struct device *dev) if (!swnode) return; - software_node_notify(dev, KOBJ_REMOVE); + if (device_is_registered(dev)) + software_node_notify(dev, KOBJ_REMOVE); set_secondary_fwnode(dev, NULL); kobject_put(&swnode->kobj); } -- 2.30.2