Commit a86537ad authored by Danilo Krummrich's avatar Danilo Krummrich Committed by Greg Kroah-Hartman
Browse files

driver core: get_dev_from_fwnode(): document potential race



Commit 9a4681a4 ("driver core: Export get_dev_from_fwnode()") made
get_dev_from_fwnode() publicly available, but didn't document the
guarantees a caller must uphold:

get_dev_from_fwnode() obtains a reference count from the device pointer
stored in a struct fwnode_handle. While having its own reference count,
struct fwnode_handle does not keep a reference count of the device it
has a pointer to.

Consequently, a caller must guarantee that it is impossible that the
last device reference is dropped and the device is released concurrently
while calling get_dev_from_fwnode(), otherwise this is a potential UAF
and hence a bug.

Thus, document this potential race condition for get_dev_from_fwnode().

Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Saravana Kannan <saravanak@google.com>
Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20250829205911.33142-1-dakr@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2b2d4c74
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -5278,6 +5278,25 @@ void device_set_node(struct device *dev, struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(device_set_node);

/**
 * get_dev_from_fwnode - Obtain a reference count of the struct device the
 * struct fwnode_handle is associated with.
 * @fwnode: The pointer to the struct fwnode_handle to obtain the struct device
 * reference count of.
 *
 * This function obtains a reference count of the device the device pointer
 * embedded in the struct fwnode_handle points to.
 *
 * Note that the struct device pointer embedded in struct fwnode_handle does
 * *not* have a reference count of the struct device itself.
 *
 * Hence, it is a UAF (and thus a bug) to call this function if the caller can't
 * guarantee that the last reference count of the corresponding struct device is
 * not dropped concurrently.
 *
 * This is possible since struct fwnode_handle has its own reference count and
 * hence can out-live the struct device it is associated with.
 */
struct device *get_dev_from_fwnode(struct fwnode_handle *fwnode)
{
	return get_device((fwnode)->dev);