[NTOS:PNP]

- Fix memory leak in IopDetectResourceConflict. While we're at it use pool tagging, kernel handles and avoid INVALID_HANDLE_VALUE.

svn path=/trunk/; revision=69227
This commit is contained in:
Thomas Faber 2015-09-14 18:58:58 +00:00
parent b4dfdfb097
commit e6b660bdce

View file

@ -1204,7 +1204,7 @@ IopDetectResourceConflict(
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE; HANDLE ResourceMapKey = NULL, ChildKey2 = NULL, ChildKey3 = NULL;
ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength; ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
PKEY_BASIC_INFORMATION KeyInformation; PKEY_BASIC_INFORMATION KeyInformation;
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
@ -1213,7 +1213,11 @@ IopDetectResourceConflict(
NTSTATUS Status; NTSTATUS Status;
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"); RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL); InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes); Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1234,7 +1238,9 @@ IopDetectResourceConflict(
else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
{ {
KeyInformationLength = RequiredLength; KeyInformationLength = RequiredLength;
KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength); KeyInformation = ExAllocatePoolWithTag(PagedPool,
KeyInformationLength,
TAG_IO);
if (!KeyInformation) if (!KeyInformation)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1252,17 +1258,22 @@ IopDetectResourceConflict(
goto cleanup; goto cleanup;
ChildKeyIndex1++; ChildKeyIndex1++;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(KeyInformation, TAG_IO);
goto cleanup; goto cleanup;
}
KeyName.Buffer = KeyInformation->Name; KeyName.Buffer = KeyInformation->Name;
KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength; KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
ResourceMapKey, ResourceMapKey,
NULL); NULL);
Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes); Status = ZwOpenKey(&ChildKey2,
ExFreePool(KeyInformation); KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
&ObjectAttributes);
ExFreePoolWithTag(KeyInformation, TAG_IO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
goto cleanup; goto cleanup;
@ -1279,7 +1290,9 @@ IopDetectResourceConflict(
else if (Status == STATUS_BUFFER_TOO_SMALL) else if (Status == STATUS_BUFFER_TOO_SMALL)
{ {
KeyInformationLength = RequiredLength; KeyInformationLength = RequiredLength;
KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength); KeyInformation = ExAllocatePoolWithTag(PagedPool,
KeyInformationLength,
TAG_IO);
if (!KeyInformation) if (!KeyInformation)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1297,17 +1310,20 @@ IopDetectResourceConflict(
goto cleanup; goto cleanup;
ChildKeyIndex2++; ChildKeyIndex2++;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(KeyInformation, TAG_IO);
goto cleanup; goto cleanup;
}
KeyName.Buffer = KeyInformation->Name; KeyName.Buffer = KeyInformation->Name;
KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength; KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
ChildKey2, ChildKey2,
NULL); NULL);
Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes); Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
ExFreePool(KeyInformation); ExFreePoolWithTag(KeyInformation, TAG_IO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
goto cleanup; goto cleanup;
@ -1324,7 +1340,9 @@ IopDetectResourceConflict(
else if (Status == STATUS_BUFFER_TOO_SMALL) else if (Status == STATUS_BUFFER_TOO_SMALL)
{ {
KeyValueInformationLength = RequiredLength; KeyValueInformationLength = RequiredLength;
KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength); KeyValueInformation = ExAllocatePoolWithTag(PagedPool,
KeyValueInformationLength,
TAG_IO);
if (!KeyValueInformation) if (!KeyValueInformation)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1341,7 +1359,10 @@ IopDetectResourceConflict(
else else
goto cleanup; goto cleanup;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(KeyValueInformation, TAG_IO);
goto cleanup; goto cleanup;
}
Status = ZwEnumerateValueKey(ChildKey3, Status = ZwEnumerateValueKey(ChildKey3,
ChildKeyIndex3, ChildKeyIndex3,
@ -1352,7 +1373,9 @@ IopDetectResourceConflict(
if (Status == STATUS_BUFFER_TOO_SMALL) if (Status == STATUS_BUFFER_TOO_SMALL)
{ {
KeyNameInformationLength = RequiredLength; KeyNameInformationLength = RequiredLength;
KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR)); KeyNameInformation = ExAllocatePoolWithTag(PagedPool,
KeyNameInformationLength + sizeof(WCHAR),
TAG_IO);
if (!KeyNameInformation) if (!KeyNameInformation)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1368,45 +1391,47 @@ IopDetectResourceConflict(
} }
else else
goto cleanup; goto cleanup;
ChildKeyIndex3++; ChildKeyIndex3++;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(KeyNameInformation, TAG_IO);
goto cleanup; goto cleanup;
}
KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL; KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
/* Skip translated entries */ /* Skip translated entries */
if (wcsstr(KeyNameInformation->Name, L".Translated")) if (wcsstr(KeyNameInformation->Name, L".Translated"))
{ {
ExFreePool(KeyNameInformation); ExFreePoolWithTag(KeyNameInformation, TAG_IO);
ExFreePoolWithTag(KeyValueInformation, TAG_IO);
continue; continue;
} }
ExFreePool(KeyNameInformation); ExFreePoolWithTag(KeyNameInformation, TAG_IO);
if (IopCheckForResourceConflict(ResourceList, if (IopCheckForResourceConflict(ResourceList,
(PCM_RESOURCE_LIST)KeyValueInformation->Data, (PCM_RESOURCE_LIST)KeyValueInformation->Data,
Silent, Silent,
ConflictingDescriptor)) ConflictingDescriptor))
{ {
ExFreePool(KeyValueInformation); ExFreePoolWithTag(KeyValueInformation, TAG_IO);
Status = STATUS_CONFLICTING_ADDRESSES; Status = STATUS_CONFLICTING_ADDRESSES;
goto cleanup; goto cleanup;
} }
ExFreePool(KeyValueInformation); ExFreePoolWithTag(KeyValueInformation, TAG_IO);
} }
} }
} }
cleanup: cleanup:
if (ResourceMapKey != INVALID_HANDLE_VALUE) if (ResourceMapKey != NULL)
ZwClose(ResourceMapKey); ObCloseHandle(ResourceMapKey, KernelMode);
if (ChildKey2 != INVALID_HANDLE_VALUE) if (ChildKey2 != NULL)
ZwClose(ChildKey2); ObCloseHandle(ChildKey2, KernelMode);
if (ChildKey3 != INVALID_HANDLE_VALUE) if (ChildKey3 != NULL)
ZwClose(ChildKey3); ObCloseHandle(ChildKey3, KernelMode);
if (Status == STATUS_NO_MORE_ENTRIES) if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;