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

commit c904983b49ee7b755f5c926c17b3b99e4042f72f
Author:     Thomas Faber <[email protected]>
AuthorDate: Sun Dec 29 13:47:40 2019 +0100
Commit:     Thomas Faber <[email protected]>
CommitDate: Tue Dec 31 15:18:17 2019 +0100

    [NTOS:IO] Use UNICODE_STRING operations in IopUnloadDriver.
    
    Fixes several overflow vulnerabilities.
---
 ntoskrnl/io/iomgr/driver.c | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index f636dc35627..8e0bea4092f 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -1186,6 +1186,7 @@ IopInitializeSystemDrivers(VOID)
 NTSTATUS NTAPI
 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
 {
+    UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
     RTL_QUERY_REGISTRY_TABLE QueryTable[2];
     UNICODE_STRING ImagePath;
     UNICODE_STRING ServiceName;
@@ -1194,7 +1195,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, 
BOOLEAN UnloadPnpDrivers)
     PDEVICE_OBJECT DeviceObject;
     PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
     NTSTATUS Status;
-    PWSTR Start;
+    USHORT LastBackslash;
     BOOLEAN SafeToUnload = TRUE;
     KPROCESSOR_MODE PreviousMode;
     UNICODE_STRING CapturedServiceName;
@@ -1230,19 +1231,34 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, 
BOOLEAN UnloadPnpDrivers)
     /*
      * Get the service name from the registry key name
      */
-    Start = wcsrchr(CapturedServiceName.Buffer, L'\\');
-    if (Start == NULL)
-        Start = CapturedServiceName.Buffer;
+    Status = 
RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END,
+                                        &CapturedServiceName,
+                                        &Backslash,
+                                        &LastBackslash);
+    if (NT_SUCCESS(Status))
+    {
+        NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
+        ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / 
sizeof(WCHAR) + 1];
+        ServiceName.Length = CapturedServiceName.Length - LastBackslash - 
sizeof(WCHAR);
+        ServiceName.MaximumLength = CapturedServiceName.MaximumLength - 
LastBackslash - sizeof(WCHAR);
+    }
     else
-        Start++;
-
-    RtlInitUnicodeString(&ServiceName, Start);
+    {
+        ServiceName = CapturedServiceName;
+    }
 
     /*
      * Construct the driver object name
      */
-    ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
-    ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
+    Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
+                          ServiceName.Length,
+                          &ObjectName.MaximumLength);
+    if (!NT_SUCCESS(Status))
+    {
+        ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
+        return Status;
+    }
+    ObjectName.Length = 0;
     ObjectName.Buffer = ExAllocatePoolWithTag(PagedPool,
                                               ObjectName.MaximumLength,
                                               TAG_IO);
@@ -1251,9 +1267,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, 
BOOLEAN UnloadPnpDrivers)
         ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME);
-    memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * 
sizeof(WCHAR));
-    ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = UNICODE_NULL;
+    NT_VERIFY(NT_SUCCESS(RtlAppendUnicodeToString(&ObjectName, 
DRIVER_ROOT_NAME)));
+    NT_VERIFY(NT_SUCCESS(RtlAppendUnicodeStringToString(&ObjectName, 
&ServiceName)));
 
     /*
      * Find the driver object

Reply via email to