summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hugh.dickins@tiscali.co.uk>2009-08-07 01:18:12 +0200
committerLen Brown <len.brown@intel.com>2009-09-01 04:12:03 +0200
commit718fb0de8ff88f71b3b91a8ee8e42e60c88e5128 (patch)
treedf81c64e25966c6956a8c43f3894fc54d16650a3
parentACPICA: Update version to 20090730 (diff)
downloadlinux-718fb0de8ff88f71b3b91a8ee8e42e60c88e5128.tar.xz
linux-718fb0de8ff88f71b3b91a8ee8e42e60c88e5128.zip
ACPI: fix NULL bug for HID/UID string
acpi_device->pnp.hardware_id and unique_id are now allocated pointers, replacing the previous arrays. acpi_device_install_notify_handler() oopsed on the NULL hid when probing the video device, and perhaps other uses are vulnerable too. So initialize those pointers to empty strings when there is no hid or uid. Also, free hardware_id and unique_id when when acpi_device is going to be freed. http://bugzilla.kernel.org/show_bug.cgi?id=14096 Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/scan.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9606af13d3b8..dc14421b93f1 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev)
struct acpi_device *acpi_dev = to_acpi_device(dev);
kfree(acpi_dev->pnp.cid_list);
+ if (acpi_dev->flags.hardware_id)
+ kfree(acpi_dev->pnp.hardware_id);
+ if (acpi_dev->flags.unique_id)
+ kfree(acpi_dev->pnp.unique_id);
kfree(acpi_dev);
}
@@ -1137,8 +1141,9 @@ static void acpi_device_set_id(struct acpi_device *device,
strcpy(device->pnp.hardware_id, hid);
device->flags.hardware_id = 1;
}
- } else
- device->pnp.hardware_id = NULL;
+ }
+ if (!device->flags.hardware_id)
+ device->pnp.hardware_id = "";
if (uid) {
device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1);
@@ -1146,8 +1151,9 @@ static void acpi_device_set_id(struct acpi_device *device,
strcpy(device->pnp.unique_id, uid);
device->flags.unique_id = 1;
}
- } else
- device->pnp.unique_id = NULL;
+ }
+ if (!device->flags.unique_id)
+ device->pnp.unique_id = "";
if (cid_list || cid_add) {
struct acpica_device_id_list *list;
@@ -1362,10 +1368,8 @@ acpi_add_single_object(struct acpi_device **child,
end:
if (!result)
*child = device;
- else {
- kfree(device->pnp.cid_list);
- kfree(device);
- }
+ else
+ acpi_device_release(&device->dev);
return result;
}