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 | |
| 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>
| -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) |
