diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-27 08:01:02 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-28 06:55:59 -0400 |
commit | 9b5c7a5a977a330ffaf83c4d383ba247c74c800f (patch) | |
tree | 43dbd7adfaf40ad4cab7b0d20c2c9bb4c4c01615 /drivers/acpi/device_pm.c | |
parent | fa1675b56537651270e79967b7f1ee4202c83bf6 (diff) |
ACPI / PM: Fix possible NULL pointer deref in acpi_pm_device_sleep_state()
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>
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r-- | drivers/acpi/device_pm.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index fd363b57a596..4c56dc830ebc 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -521,7 +521,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) | |||
521 | { | 521 | { |
522 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | 522 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); |
523 | struct acpi_device *adev; | 523 | struct acpi_device *adev; |
524 | int ret, d_max; | 524 | int ret, d_min, d_max; |
525 | 525 | ||
526 | if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD) | 526 | if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD) |
527 | return -EINVAL; | 527 | return -EINVAL; |
@@ -540,19 +540,23 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) | |||
540 | } | 540 | } |
541 | 541 | ||
542 | ret = acpi_dev_pm_get_state(dev, adev, acpi_target_system_state(), | 542 | ret = acpi_dev_pm_get_state(dev, adev, acpi_target_system_state(), |
543 | d_min_p, &d_max); | 543 | &d_min, &d_max); |
544 | if (ret) | 544 | if (ret) |
545 | return ret; | 545 | return ret; |
546 | 546 | ||
547 | if (d_max_in < *d_min_p) | 547 | if (d_max_in < d_min) |
548 | return -EINVAL; | 548 | return -EINVAL; |
549 | 549 | ||
550 | if (d_max > d_max_in) { | 550 | if (d_max > d_max_in) { |
551 | for (d_max = d_max_in; d_max > *d_min_p; d_max--) { | 551 | for (d_max = d_max_in; d_max > d_min; d_max--) { |
552 | if (adev->power.states[d_max].flags.valid) | 552 | if (adev->power.states[d_max].flags.valid) |
553 | break; | 553 | break; |
554 | } | 554 | } |
555 | } | 555 | } |
556 | |||
557 | if (d_min_p) | ||
558 | *d_min_p = d_min; | ||
559 | |||
556 | return d_max; | 560 | return d_max; |
557 | } | 561 | } |
558 | EXPORT_SYMBOL(acpi_pm_device_sleep_state); | 562 | EXPORT_SYMBOL(acpi_pm_device_sleep_state); |