]> rtime.felk.cvut.cz Git - linux-imx.git/commitdiff
ACPI / PM: Fix possible NULL pointer deref in acpi_pm_device_sleep_state()
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 27 Jun 2013 12:01:02 +0000 (14:01 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 28 Jun 2013 10:55:59 +0000 (12:55 +0200)
After commit fa1675b (ACPI / PM: Rework and clean up
acpi_dev_pm_get_state()) a NULL pointer dereference will take place
if NULL is passed to acpi_pm_device_sleep_state() as the second
argument.

Fix that by avoiding to use the pointer that may be NULL until
it's necessary to store a return value at the location pointed to
by it (if not NULL).

Reported-and-tested-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/device_pm.c

index fd363b57a5963b028a228791573456301dfdbc53..4c56dc830ebcecf0b267fd2954b87727d0fcc465 100644 (file)
@@ -521,7 +521,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
 {
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
-       int ret, d_max;
+       int ret, d_min, d_max;
 
        if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD)
                return -EINVAL;
@@ -540,19 +540,23 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
        }
 
        ret = acpi_dev_pm_get_state(dev, adev, acpi_target_system_state(),
-                                   d_min_p, &d_max);
+                                   &d_min, &d_max);
        if (ret)
                return ret;
 
-       if (d_max_in < *d_min_p)
+       if (d_max_in < d_min)
                return -EINVAL;
 
        if (d_max > d_max_in) {
-               for (d_max = d_max_in; d_max > *d_min_p; d_max--) {
+               for (d_max = d_max_in; d_max > d_min; d_max--) {
                        if (adev->power.states[d_max].flags.valid)
                                break;
                }
        }
+
+       if (d_min_p)
+               *d_min_p = d_min;
+
        return d_max;
 }
 EXPORT_SYMBOL(acpi_pm_device_sleep_state);