https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e09d1dec7ae938e27ca3013d2ffefae6bf78d230

commit e09d1dec7ae938e27ca3013d2ffefae6bf78d230
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Thu Jun 10 22:31:45 2021 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Wed Jun 16 22:18:02 2021 +0200

    [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.
---
 ntoskrnl/io/iomgr/driver.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index 6d82bfc536e..f48a85a9705 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -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;
 }
 
 /*

Reply via email to