[NTOS:IO] Fix basicInfo handling in IopGetDriverNames().

- Fix CID 1477246: Uninitialized pointer read (UNINIT) (happens in
  the last ExFreePoolWithTag(basicInfo, TAG_IO) call when the
  "(!NT_SUCCESS(status) || ServiceName != NULL)" case is not taken).

- Centralize all the ExFreePoolWithTag(basicInfo, TAG_IO) cleanups
  at the end of the function.

- Both cases "(driverName.Buffer == NULL)" and "(ServiceName != NULL)"
  can only be taken when basicInfo != NULL, so assert on this fact.
This commit is contained in:
Hermès Bélusca-Maïto
2021-06-10 22:31:45 +02:00
parent 0d28f27156
commit e09d1dec7a

View File

@@ -163,7 +163,7 @@ IopGetDriverNames(
/* Check whether we need to get ServiceName as well, either to construct
* the driver name (because we could not use "ObjectName"), or because
* it is requested by the caller. */
PKEY_BASIC_INFORMATION basicInfo;
PKEY_BASIC_INFORMATION basicInfo = NULL;
if (!NT_SUCCESS(status) || ServiceName != NULL)
{
/* Retrieve the necessary buffer size */
@@ -197,19 +197,20 @@ IopGetDriverNames(
* it will be either "\Driver\<ServiceName>" or "\FileSystem\<ServiceName>" */
if (driverName.Buffer == NULL)
{
ASSERT(basicInfo); // Container for serviceName
/* Retrieve the driver type */
ULONG driverType;
status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
if (!NT_SUCCESS(status))
{
ExFreePoolWithTag(basicInfo, TAG_IO);
return status;
goto Cleanup;
}
if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
{
ExFreePool(kvInfo);
ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
return STATUS_ILL_FORMED_SERVICE_ENTRY;
status = STATUS_ILL_FORMED_SERVICE_ENTRY;
goto Cleanup;
}
driverType = *(PULONG)((ULONG_PTR)kvInfo + kvInfo->DataOffset);
ExFreePool(kvInfo);
@@ -227,8 +228,8 @@ IopGetDriverNames(
driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
if (!driverName.Buffer)
{
ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
return STATUS_INSUFFICIENT_RESOURCES;
status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
@@ -241,24 +242,30 @@ IopGetDriverNames(
if (ServiceName != NULL)
{
ASSERT(basicInfo); // Container for serviceName
/* Allocate a copy for the caller */
PWCHAR buf = ExAllocatePoolWithTag(PagedPool, serviceName.Length, TAG_IO);
if (!buf)
{
ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
ExFreePoolWithTag(driverName.Buffer, TAG_IO);
return STATUS_INSUFFICIENT_RESOURCES;
status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
ServiceName->MaximumLength = serviceName.Length;
ServiceName->Length = serviceName.Length;
ServiceName->Buffer = buf;
}
ExFreePoolWithTag(basicInfo, TAG_IO); // container for ServiceName
*DriverName = driverName;
status = STATUS_SUCCESS;
return STATUS_SUCCESS;
Cleanup:
if (basicInfo)
ExFreePoolWithTag(basicInfo, TAG_IO);
return status;
}
/*