Re: [PATCH v1 1/3] ACPI: bus: Introduce acpi_bus_get_primary_device()
From: Andy Shevchenko
Date: Mon Aug 10 2026 - 11:59:56 EST
On Mon, Aug 10, 2026 at 01:33:41PM +0200, Rafael J. Wysocki wrote:
> From: "Rafael J. Wysocki" <rafael.j.wysocki@xxxxxxxxx>
>
> The function used for obtaining the first "physical" device for which
> the given ACPI one is the ACPI companion, acpi_get_first_physical_node(),
> may return a stale device pointer (mostly in theory) because
> acpi_unbind_one() may run as a whole after dropping the ACPI device's
> physical_node_lock in acpi_get_first_physical_node() and before it
> returns. The last reference to the "physical" device may be dropped
> then before the pointer to it is returned to the caller.
>
> If that happens and the acpi_get_first_physical_node() caller invokes
> get_device() on the pointer obtained from it, which is done by the
> majority of its callers, a use-after-free will occur.
>
> To prepare for addressing this problem, introduce a new function for
> getting the first "physical" device associated with the given ACPI one
> (the "primary physical device") that will also reference count the
> device in question before returning a pointer to it.
>
> Make that new function and acpi_get_first_physical_node() share the
> physical node list lookup code.
>
> No intentional functional impact.
...
> +static struct device *primary_physical_device(struct acpi_device *adev)
> +{
> + if (list_empty(&adev->physical_node_list))
> + return NULL;
> +
> + return list_first_entry(&adev->physical_node_list,
> + struct acpi_device_physical_node, node)->dev;
This is open-coded list_first_entry_or_null().
I see the ->dev, so having temporary variable will suit this
struct ... *...;
... = list_first_entry_or_null(...);
if (...)
return ...->dev;
return NULL;
> +}
--
With Best Regards,
Andy Shevchenko