- Fix a buffer overrun that caused a BSOD with ACPI enabled on Hyper-V
- Dynamically allocate the hardware ID buffer to prevent another HID overrun
- Switched sprintf to snprintf to prevent this from happening to another ID

svn path=/trunk/; revision=63344
This commit is contained in:
Cameron Gutman 2014-05-18 05:52:09 +00:00
parent 2736ab0dca
commit 689159fedc
2 changed files with 30 additions and 21 deletions

View file

@ -1142,7 +1142,7 @@ acpi_bus_add (
char *uid = NULL; char *uid = NULL;
ACPI_PNP_DEVICE_ID_LIST *cid_list = NULL; ACPI_PNP_DEVICE_ID_LIST *cid_list = NULL;
int i = 0; int i = 0;
char static_uid_buffer[5]; acpi_unique_id static_uid_buffer;
if (!child) if (!child)
return_VALUE(AE_BAD_PARAMETER); return_VALUE(AE_BAD_PARAMETER);
@ -1165,15 +1165,15 @@ acpi_bus_add (
*/ */
switch (type) { switch (type) {
case ACPI_BUS_TYPE_SYSTEM: case ACPI_BUS_TYPE_SYSTEM:
sprintf(device->pnp.bus_id, "%s", "ACPI"); snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "ACPI");
break; break;
case ACPI_BUS_TYPE_POWER_BUTTONF: case ACPI_BUS_TYPE_POWER_BUTTONF:
case ACPI_BUS_TYPE_POWER_BUTTON: case ACPI_BUS_TYPE_POWER_BUTTON:
sprintf(device->pnp.bus_id, "%s", "PWRF"); snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "PWRF");
break; break;
case ACPI_BUS_TYPE_SLEEP_BUTTONF: case ACPI_BUS_TYPE_SLEEP_BUTTONF:
case ACPI_BUS_TYPE_SLEEP_BUTTON: case ACPI_BUS_TYPE_SLEEP_BUTTON:
sprintf(device->pnp.bus_id, "%s", "SLPF"); snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "SLPF");
break; break;
default: default:
buffer.Length = sizeof(bus_id); buffer.Length = sizeof(bus_id);
@ -1188,7 +1188,7 @@ acpi_bus_add (
else else
break; break;
} }
sprintf(device->pnp.bus_id, "%s", bus_id); snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", bus_id);
buffer.Pointer = NULL; buffer.Pointer = NULL;
/* HACK: Skip HPET */ /* HACK: Skip HPET */
@ -1277,12 +1277,12 @@ acpi_bus_add (
case ACPI_BUS_TYPE_POWER: case ACPI_BUS_TYPE_POWER:
hid = ACPI_POWER_HID; hid = ACPI_POWER_HID;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (PowerDeviceCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerDeviceCount++));
break; break;
case ACPI_BUS_TYPE_PROCESSOR: case ACPI_BUS_TYPE_PROCESSOR:
hid = ACPI_PROCESSOR_HID; hid = ACPI_PROCESSOR_HID;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "_%d", (ProcessorCount++)); snprintf(uid, sizeof(static_uid_buffer), "_%d", (ProcessorCount++));
break; break;
case ACPI_BUS_TYPE_SYSTEM: case ACPI_BUS_TYPE_SYSTEM:
hid = ACPI_SYSTEM_HID; hid = ACPI_SYSTEM_HID;
@ -1290,27 +1290,27 @@ acpi_bus_add (
case ACPI_BUS_TYPE_THERMAL: case ACPI_BUS_TYPE_THERMAL:
hid = ACPI_THERMAL_HID; hid = ACPI_THERMAL_HID;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (ThermalZoneCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (ThermalZoneCount++));
break; break;
case ACPI_BUS_TYPE_POWER_BUTTON: case ACPI_BUS_TYPE_POWER_BUTTON:
hid = ACPI_BUTTON_HID_POWER; hid = ACPI_BUTTON_HID_POWER;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (PowerButtonCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerButtonCount++));
break; break;
case ACPI_BUS_TYPE_POWER_BUTTONF: case ACPI_BUS_TYPE_POWER_BUTTONF:
hid = ACPI_BUTTON_HID_POWERF; hid = ACPI_BUTTON_HID_POWERF;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (FixedPowerButtonCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedPowerButtonCount++));
break; break;
case ACPI_BUS_TYPE_SLEEP_BUTTON: case ACPI_BUS_TYPE_SLEEP_BUTTON:
hid = ACPI_BUTTON_HID_SLEEP; hid = ACPI_BUTTON_HID_SLEEP;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (SleepButtonCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (SleepButtonCount++));
break; break;
case ACPI_BUS_TYPE_SLEEP_BUTTONF: case ACPI_BUS_TYPE_SLEEP_BUTTONF:
hid = ACPI_BUTTON_HID_SLEEPF; hid = ACPI_BUTTON_HID_SLEEPF;
uid = static_uid_buffer; uid = static_uid_buffer;
sprintf(uid, "%d", (FixedSleepButtonCount++)); snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedSleepButtonCount++));
break; break;
} }
@ -1321,16 +1321,19 @@ acpi_bus_add (
*/ */
if (((ACPI_HANDLE)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { if (((ACPI_HANDLE)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
hid = ACPI_BUS_HID; hid = ACPI_BUS_HID;
sprintf(device->pnp.device_name, "%s", ACPI_BUS_DEVICE_NAME); snprintf(device->pnp.device_name, sizeof(device->pnp.device_name), "%s", ACPI_BUS_DEVICE_NAME);
sprintf(device->pnp.device_class, "%s", ACPI_BUS_CLASS); snprintf(device->pnp.device_class, sizeof(device->pnp.device_class), "%s", ACPI_BUS_CLASS);
} }
if (hid) { if (hid) {
sprintf(device->pnp.hardware_id, "%s", hid); device->pnp.hardware_id = ExAllocatePoolWithTag(NonPagedPool, strlen(hid) + 1, 'IPCA');
device->flags.hardware_id = 1; if (device->pnp.hardware_id) {
snprintf(device->pnp.hardware_id, strlen(hid) + 1, "%s", hid);
device->flags.hardware_id = 1;
}
} }
if (uid) { if (uid) {
sprintf(device->pnp.unique_id, "%s", uid); snprintf(device->pnp.unique_id, sizeof(device->pnp.unique_id), "%s", uid);
device->flags.unique_id = 1; device->flags.unique_id = 1;
} }
@ -1434,6 +1437,9 @@ end:
if (device->pnp.cid_list) { if (device->pnp.cid_list) {
ExFreePoolWithTag(device->pnp.cid_list, 'IPCA'); ExFreePoolWithTag(device->pnp.cid_list, 'IPCA');
} }
if (device->pnp.hardware_id) {
ExFreePoolWithTag(device->pnp.hardware_id, 'IPCA');
}
ExFreePoolWithTag(device, 'IPCA'); ExFreePoolWithTag(device, 'IPCA');
return_VALUE(result); return_VALUE(result);
} }
@ -1454,9 +1460,12 @@ acpi_bus_remove (
acpi_device_unregister(device); acpi_device_unregister(device);
if (device && device->pnp.cid_list) if (device->pnp.cid_list)
ExFreePoolWithTag(device->pnp.cid_list, 'IPCA'); ExFreePoolWithTag(device->pnp.cid_list, 'IPCA');
if (device->pnp.hardware_id)
ExFreePoolWithTag(device->pnp.hardware_id, 'IPCA');
if (device) if (device)
ExFreePoolWithTag(device, 'IPCA'); ExFreePoolWithTag(device, 'IPCA');

View file

@ -164,10 +164,10 @@ struct acpi_device_flags {
/* Plug and Play */ /* Plug and Play */
typedef char acpi_bus_id[20]; typedef char acpi_bus_id[8];
typedef unsigned long acpi_bus_address; typedef unsigned long acpi_bus_address;
typedef char acpi_hardware_id[20]; typedef char *acpi_hardware_id;
typedef char acpi_unique_id[20]; typedef char acpi_unique_id[9];
typedef char acpi_device_name[40]; typedef char acpi_device_name[40];
typedef char acpi_device_class[20]; typedef char acpi_device_class[20];