[NTOS:PNP]

- Avoid memory leaks in IopActionInterrogateDeviceStack. Noticed by Vadim Galyant.
CORE-12732

svn path=/trunk/; revision=74023
This commit is contained in:
Thomas Faber 2017-03-02 09:39:40 +00:00
parent b5fd932bef
commit ebc3d8bfbc

View file

@ -1869,6 +1869,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
PVOID Context) PVOID Context)
{ {
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PWSTR InformationString;
PDEVICE_NODE ParentDeviceNode; PDEVICE_NODE ParentDeviceNode;
WCHAR InstancePath[MAX_PATH]; WCHAR InstancePath[MAX_PATH];
IO_STACK_LOCATION Stack; IO_STACK_LOCATION Stack;
@ -1934,17 +1935,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
&IoStatusBlock, &IoStatusBlock,
IRP_MN_QUERY_ID, IRP_MN_QUERY_ID,
&Stack); &Stack);
if (NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
/* Copy the device id string */
wcscpy(InstancePath, (PWSTR)IoStatusBlock.Information);
/*
* FIXME: Check for valid characters, if there is invalid characters
* then bugcheck.
*/
}
else
{ {
DPRINT1("IopInitiatePnpIrp() failed (Status %x)\n", Status); DPRINT1("IopInitiatePnpIrp() failed (Status %x)\n", Status);
@ -1952,6 +1943,17 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* Copy the device id string */
InformationString = (PWSTR)IoStatusBlock.Information;
wcscpy(InstancePath, InformationString);
/*
* FIXME: Check for valid characters, if there is invalid characters
* then bugcheck.
*/
ExFreePoolWithTag(InformationString, 0);
DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n"); DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities); Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
@ -1998,26 +2000,33 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
&Stack); &Stack);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
InformationString = (PWSTR)IoStatusBlock.Information;
/* Append the instance id string */ /* Append the instance id string */
wcscat(InstancePath, L"\\"); wcscat(InstancePath, L"\\");
if (ParentIdPrefix.Length > 0) if (ParentIdPrefix.Length > 0)
{ {
/* Add information from parent bus device to InstancePath */ /* Add information from parent bus device to InstancePath */
wcscat(InstancePath, ParentIdPrefix.Buffer); wcscat(InstancePath, ParentIdPrefix.Buffer);
if (IoStatusBlock.Information && *(PWSTR)IoStatusBlock.Information) if (InformationString && *InformationString)
{ {
wcscat(InstancePath, L"&"); wcscat(InstancePath, L"&");
} }
} }
if (IoStatusBlock.Information) if (InformationString)
{ {
wcscat(InstancePath, (PWSTR)IoStatusBlock.Information); wcscat(InstancePath, InformationString);
} }
/* /*
* FIXME: Check for valid characters, if there is invalid characters * FIXME: Check for valid characters, if there is invalid characters
* then bugcheck * then bugcheck
*/ */
if (InformationString)
{
ExFreePoolWithTag(InformationString, 0);
}
} }
else else
{ {
@ -2076,13 +2085,14 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
&IoStatusBlock, &IoStatusBlock,
IRP_MN_QUERY_DEVICE_TEXT, IRP_MN_QUERY_DEVICE_TEXT,
&Stack); &Stack);
InformationString = NT_SUCCESS(Status) ? (PWSTR)IoStatusBlock.Information
: NULL;
/* This key is mandatory, so even if the Irp fails, we still write it */ /* This key is mandatory, so even if the Irp fails, we still write it */
RtlInitUnicodeString(&ValueName, L"DeviceDesc"); RtlInitUnicodeString(&ValueName, L"DeviceDesc");
if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND) if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
{ {
if (NT_SUCCESS(Status) && if (InformationString &&
IoStatusBlock.Information && *InformationString != UNICODE_NULL)
(*(PWSTR)IoStatusBlock.Information != 0))
{ {
/* This key is overriden when a driver is installed. Don't write the /* This key is overriden when a driver is installed. Don't write the
* new description if another one already exists */ * new description if another one already exists */
@ -2090,8 +2100,8 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
&ValueName, &ValueName,
0, 0,
REG_SZ, REG_SZ,
(PVOID)IoStatusBlock.Information, InformationString,
((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR)); ((ULONG)wcslen(InformationString) + 1) * sizeof(WCHAR));
} }
else else
{ {
@ -2112,6 +2122,11 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
} }
} }
if (InformationString)
{
ExFreePoolWithTag(InformationString, 0);
}
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n"); DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation; Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
@ -2122,18 +2137,21 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
&Stack); &Stack);
if (NT_SUCCESS(Status) && IoStatusBlock.Information) if (NT_SUCCESS(Status) && IoStatusBlock.Information)
{ {
DPRINT("LocationInformation: %S\n", (PWSTR)IoStatusBlock.Information); InformationString = (PWSTR)IoStatusBlock.Information;
DPRINT("LocationInformation: %S\n", InformationString);
RtlInitUnicodeString(&ValueName, L"LocationInformation"); RtlInitUnicodeString(&ValueName, L"LocationInformation");
Status = ZwSetValueKey(InstanceKey, Status = ZwSetValueKey(InstanceKey,
&ValueName, &ValueName,
0, 0,
REG_SZ, REG_SZ,
(PVOID)IoStatusBlock.Information, InformationString,
((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR)); ((ULONG)wcslen(InformationString) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status); DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
} }
ExFreePoolWithTag(InformationString, 0);
} }
else else
{ {
@ -2153,7 +2171,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
DeviceNode->ChildBusNumber = BusInformation->BusNumber; DeviceNode->ChildBusNumber = BusInformation->BusNumber;
DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType; DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid); DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
ExFreePool(BusInformation); ExFreePoolWithTag(BusInformation, 0);
} }
else else
{ {