aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-06-27 08:01:02 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-06-28 06:55:59 -0400
commit9b5c7a5a977a330ffaf83c4d383ba247c74c800f (patch)
tree43dbd7adfaf40ad4cab7b0d20c2c9bb4c4c01615 /drivers/acpi/device_pm.c
parentfa1675b56537651270e79967b7f1ee4202c83bf6 (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.c12
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}
558EXPORT_SYMBOL(acpi_pm_device_sleep_state); 562EXPORT_SYMBOL(acpi_pm_device_sleep_state);