From aec3d9cc8f890df41fbaa697a0249a78ad98db8f Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Fri, 19 Mar 2021 01:07:22 +0300 Subject: [PATCH] [NTOS:IO][NTOS:PNP] Fix incorrect usage of IopGetRegistryValue KEY_VALUE_FULL_INFORMATION was not always freed properly --- ntoskrnl/io/iomgr/driver.c | 7 ++- ntoskrnl/io/pnpmgr/devaction.c | 90 ++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 42 deletions(-) diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c index 602cd487fb7..24f6084a892 100644 --- a/ntoskrnl/io/iomgr/driver.c +++ b/ntoskrnl/io/iomgr/driver.c @@ -195,7 +195,12 @@ IopGetDriverNames( if (driverName.Buffer == NULL) { status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo); - if (!NT_SUCCESS(status) || kvInfo->Type != REG_DWORD) + if (!NT_SUCCESS(status)) + { + ExFreePoolWithTag(basicInfo, TAG_IO); + return status; + } + if (kvInfo->Type != REG_DWORD) { ExFreePool(kvInfo); ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c index 5d354ddc62c..aa1ac12f6c2 100644 --- a/ntoskrnl/io/pnpmgr/devaction.c +++ b/ntoskrnl/io/pnpmgr/devaction.c @@ -419,11 +419,15 @@ PiAttachFilterDriversCallback( SERVICE_LOAD_TYPE startType = DisableLoad; Status = IopGetRegistryValue(serviceHandle, L"Start", &kvInfo); - if (NT_SUCCESS(Status) && kvInfo->Type == REG_DWORD) + if (NT_SUCCESS(Status)) { - RtlMoveMemory(&startType, - (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), - sizeof(startType)); + if (kvInfo->Type == REG_DWORD) + { + RtlMoveMemory(&startType, + (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), + sizeof(startType)); + } + ExFreePool(kvInfo); } @@ -621,52 +625,56 @@ PiCallDriverAddDevice( // try to get the class GUID of an instance and its registry key Status = IopGetRegistryValue(SubKey, REGSTR_VAL_CLASSGUID, &kvInfo); - if (NT_SUCCESS(Status) && kvInfo->Type == REG_SZ && kvInfo->DataLength > sizeof(WCHAR)) + if (NT_SUCCESS(Status)) { - UNICODE_STRING classGUID = { - .MaximumLength = kvInfo->DataLength, - .Length = kvInfo->DataLength - sizeof(UNICODE_NULL), - .Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset) - }; - HANDLE ccsControlHandle; + if (kvInfo->Type == REG_SZ && kvInfo->DataLength > sizeof(WCHAR)) + { + UNICODE_STRING classGUID = { + .MaximumLength = kvInfo->DataLength, + .Length = kvInfo->DataLength - sizeof(UNICODE_NULL), + .Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset) + }; + HANDLE ccsControlHandle; - Status = IopOpenRegistryKeyEx(&ccsControlHandle, NULL, &ccsControlClass, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n", - &ccsControlClass, Status); - } - else - { - // open the CCS\Control\Class\ key - Status = IopOpenRegistryKeyEx(&ClassKey, ccsControlHandle, &classGUID, KEY_READ); - ZwClose(ccsControlHandle); + Status = IopOpenRegistryKeyEx(&ccsControlHandle, NULL, &ccsControlClass, KEY_READ); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open class key \"%wZ\" (status %x)\n", &classGUID, Status); - } - } - - if (ClassKey) - { - // Check the Properties key of a class too - // Windows fills some device properties from this key (which is protected) - // TODO: add the device properties from this key - - UNICODE_STRING properties = RTL_CONSTANT_STRING(REGSTR_KEY_DEVICE_PROPERTIES); - HANDLE propertiesHandle; - - Status = IopOpenRegistryKeyEx(&propertiesHandle, ClassKey, &properties, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT("Properties key failed to open for \"%wZ\" (status %x)\n", - &classGUID, Status); + DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n", + &ccsControlClass, Status); } else { - ZwClose(propertiesHandle); + // open the CCS\Control\Class\ key + Status = IopOpenRegistryKeyEx(&ClassKey, ccsControlHandle, &classGUID, KEY_READ); + ZwClose(ccsControlHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open class key \"%wZ\" (status %x)\n", &classGUID, Status); + } + } + + if (ClassKey) + { + // Check the Properties key of a class too + // Windows fills some device properties from this key (which is protected) + // TODO: add the device properties from this key + + UNICODE_STRING properties = RTL_CONSTANT_STRING(REGSTR_KEY_DEVICE_PROPERTIES); + HANDLE propertiesHandle; + + Status = IopOpenRegistryKeyEx(&propertiesHandle, ClassKey, &properties, KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT("Properties key failed to open for \"%wZ\" (status %x)\n", + &classGUID, Status); + } + else + { + ZwClose(propertiesHandle); + } } } + ExFreePool(kvInfo); }