diff options
author | Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> | 2011-07-12 04:03:28 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-07-16 18:54:59 -0400 |
commit | e80bba4b5108c6479379740201b0a5d9da5ffbac (patch) | |
tree | 34634eebb8dc8f17e8654ffff0d5b6b2fb3a370b /drivers/acpi/battery.c | |
parent | 9c921c22a7f33397a6774d7fa076db9b6a0fd669 (diff) |
ACPI / Battery: avoid acpi_battery_add() use-after-free
When acpi_battery_add_fs() fails the error handling code does not clean
up completely. Moreover, it does not return resulting in a
use-after-free.
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r-- | drivers/acpi/battery.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 40bf01d42cc3..c771768f57c8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -986,21 +986,27 @@ static int acpi_battery_add(struct acpi_device *device) | |||
986 | #ifdef CONFIG_ACPI_PROCFS_POWER | 986 | #ifdef CONFIG_ACPI_PROCFS_POWER |
987 | result = acpi_battery_add_fs(device); | 987 | result = acpi_battery_add_fs(device); |
988 | #endif | 988 | #endif |
989 | if (!result) { | 989 | if (result) { |
990 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | ||
991 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | ||
992 | device->status.battery_present ? "present" : "absent"); | ||
993 | } else { | ||
994 | #ifdef CONFIG_ACPI_PROCFS_POWER | 990 | #ifdef CONFIG_ACPI_PROCFS_POWER |
995 | acpi_battery_remove_fs(device); | 991 | acpi_battery_remove_fs(device); |
996 | #endif | 992 | #endif |
997 | kfree(battery); | 993 | goto fail; |
998 | } | 994 | } |
999 | 995 | ||
996 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | ||
997 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | ||
998 | device->status.battery_present ? "present" : "absent"); | ||
999 | |||
1000 | battery->pm_nb.notifier_call = battery_notify; | 1000 | battery->pm_nb.notifier_call = battery_notify; |
1001 | register_pm_notifier(&battery->pm_nb); | 1001 | register_pm_notifier(&battery->pm_nb); |
1002 | 1002 | ||
1003 | return result; | 1003 | return result; |
1004 | |||
1005 | fail: | ||
1006 | sysfs_remove_battery(battery); | ||
1007 | mutex_destroy(&battery->lock); | ||
1008 | kfree(battery); | ||
1009 | return result; | ||
1004 | } | 1010 | } |
1005 | 1011 | ||
1006 | static int acpi_battery_remove(struct acpi_device *device, int type) | 1012 | static int acpi_battery_remove(struct acpi_device *device, int type) |