Message ID | 11974495.O9o76ZdvQC@kreacher |
---|---|
State | New |
Headers | show |
Series | ACPI: bus: Avoid non-ACPI device objects in walks over children | expand |
Hi Rafael, On Fri, Apr 22, 2022 at 05:13:48PM +0200, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > When walking the children of an ACPI device, take extra care to avoid > using to_acpi_device() on the ones that are not ACPI devices, because > that may lead to out-of-bounds access and memory corruption. > > While at it, make the function passed to acpi_dev_for_each_child() > take a struct acpi_device pointer argument (instead of a struct device > one), so it is more straightforward to use. > > Fixes: b7dd6298db81 ("ACPI: PM: Introduce acpi_dev_power_up_children_with_adr()") > Reported-by: kernel test robot <oliver.sang@intel.com> > BugLink: https://lore.kernel.org/lkml/20220420064725.GB16310@xsang-OptiPlex-9020/ > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > --- > > The commit being fixed is present in linux-next. > > --- > drivers/acpi/bus.c | 24 ++++++++++++++++++++++-- > drivers/acpi/device_pm.c | 5 +---- > include/acpi/acpi_bus.h | 2 +- > 3 files changed, 24 insertions(+), 7 deletions(-) > > Index: linux-pm/drivers/acpi/bus.c > =================================================================== > --- linux-pm.orig/drivers/acpi/bus.c > +++ linux-pm/drivers/acpi/bus.c > @@ -1070,10 +1070,30 @@ int acpi_bus_for_each_dev(int (*fn)(stru > } > EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev); > > +struct acpi_dev_walk_context { > + int (*fn)(struct acpi_device *, void *); > + void *data; > +}; > + > +static int acpi_dev_for_one_check(struct device *dev, void *context) > +{ > + struct acpi_dev_walk_context *adwc = context; > + > + if (dev->bus != &acpi_bus_type) > + return 0; I wonder if it make sense to add dev_is_acpi() that does the above analoguos to dev_is_pci()? Regardless of that, Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Index: linux-pm/drivers/acpi/bus.c =================================================================== --- linux-pm.orig/drivers/acpi/bus.c +++ linux-pm/drivers/acpi/bus.c @@ -1070,10 +1070,30 @@ int acpi_bus_for_each_dev(int (*fn)(stru } EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev); +struct acpi_dev_walk_context { + int (*fn)(struct acpi_device *, void *); + void *data; +}; + +static int acpi_dev_for_one_check(struct device *dev, void *context) +{ + struct acpi_dev_walk_context *adwc = context; + + if (dev->bus != &acpi_bus_type) + return 0; + + return adwc->fn(to_acpi_device(dev), adwc->data); +} + int acpi_dev_for_each_child(struct acpi_device *adev, - int (*fn)(struct device *, void *), void *data) + int (*fn)(struct acpi_device *, void *), void *data) { - return device_for_each_child(&adev->dev, data, fn); + struct acpi_dev_walk_context adwc = { + .fn = fn, + .data = data, + }; + + return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check); } /* -------------------------------------------------------------------------- Index: linux-pm/include/acpi/acpi_bus.h =================================================================== --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -482,7 +482,7 @@ extern struct bus_type acpi_bus_type; int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data); int acpi_dev_for_each_child(struct acpi_device *adev, - int (*fn)(struct device *, void *), void *data); + int (*fn)(struct acpi_device *, void *), void *data); /* * Events Index: linux-pm/drivers/acpi/device_pm.c =================================================================== --- linux-pm.orig/drivers/acpi/device_pm.c +++ linux-pm/drivers/acpi/device_pm.c @@ -429,11 +429,8 @@ bool acpi_bus_power_manageable(acpi_hand } EXPORT_SYMBOL(acpi_bus_power_manageable); -static int acpi_power_up_if_adr_present(struct device *dev, void *not_used) +static int acpi_power_up_if_adr_present(struct acpi_device *adev, void *not_used) { - struct acpi_device *adev; - - adev = to_acpi_device(dev); if (!(adev->flags.power_manageable && adev->pnp.type.bus_address)) return 0;