[NTOSKRNL] Probe parameters in NtAllocateUuids() if called from user-mode
authorPierre Schweitzer <pierre@reactos.org>
Wed, 19 Dec 2018 07:07:28 +0000 (08:07 +0100)
committerPierre Schweitzer <pierre@reactos.org>
Wed, 19 Dec 2018 07:09:04 +0000 (08:09 +0100)
This will avoid that userland applications can trigger an invalid write in
the kernel (and thus, a BSOD).

CORE-15462

ntoskrnl/ex/uuid.c

index e43f6d1..ca6ed09 100644 (file)
@@ -319,9 +319,39 @@ NtAllocateUuids(OUT PULARGE_INTEGER Time,
     ULARGE_INTEGER IntTime;
     ULONG IntRange;
     NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode;
 
     PAGED_CODE();
 
+    /* Probe if user mode */
+    PreviousMode = ExGetPreviousMode();
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            ProbeForWrite(Time,
+                          sizeof(ULARGE_INTEGER),
+                          sizeof(ULONG));
+
+            ProbeForWrite(Range,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+
+            ProbeForWrite(Sequence,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+
+            ProbeForWrite(Seed,
+                          SEED_BUFFER_SIZE,
+                          sizeof(UCHAR));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        }
+        _SEH2_END;
+    }
+
     ExAcquireFastMutex(&UuidMutex);
 
     if (!UuidSequenceInitialized)
@@ -358,13 +388,22 @@ NtAllocateUuids(OUT PULARGE_INTEGER Time,
 
     ExReleaseFastMutex(&UuidMutex);
 
-    Time->QuadPart = IntTime.QuadPart;
-    *Range = IntRange;
-    *Sequence = UuidSequence;
+    /* Write back LUID to caller */
+    _SEH2_TRY
+    {
+        Time->QuadPart = IntTime.QuadPart;
+        *Range = IntRange;
+        *Sequence = UuidSequence;
 
-    RtlCopyMemory(Seed,
-                  UuidSeed,
-                  SEED_BUFFER_SIZE);
+        RtlCopyMemory(Seed,
+                      UuidSeed,
+                      SEED_BUFFER_SIZE);
+    }
+    _SEH2_EXCEPT(ExSystemExceptionFilter())
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
 
     return STATUS_SUCCESS;
 }