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

commit d86301f72bb562b89c8dfa63781b764742317f8b
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Mon Oct 5 02:15:14 2020 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Mon Oct 5 02:22:45 2020 +0200

    [NTDLL:CSR] Perform more thorough validation of the parameters in 
CsrAllocateCaptureBuffer().
    
    Complements commit 7e2db773.
    
    - Validate the argument count.
    
    - Validate the total buffer size: the total size of the header plus
      the pointer-offset array and the provided buffer, together with
      the alignment padding for each argument, must be less than MAXLONG
      aligned to 4-byte boundary.
---
 dll/ntdll/csr/capture.c | 35 ++++++++++++++++++++++++++++-------
 dll/ntdll/csr/connect.c |  2 +-
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/dll/ntdll/csr/capture.c b/dll/ntdll/csr/capture.c
index 759f74bcdf9..1a388d467a4 100644
--- a/dll/ntdll/csr/capture.c
+++ b/dll/ntdll/csr/capture.c
@@ -91,13 +91,35 @@ CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
                          IN ULONG BufferSize)
 {
     PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG OffsetsArraySize;
+    ULONG MaximumSize;
 
-    /* Validate size */
-    if (BufferSize >= MAXLONG) return NULL;
+    /* Validate the argument count. Note that on server side, CSRSRV
+     * limits the count to MAXUSHORT; here we are a bit more lenient. */
+    if (ArgumentCount > (MAXLONG / sizeof(ULONG_PTR)))
+        return NULL;
+
+    OffsetsArraySize = ArgumentCount * sizeof(ULONG_PTR);
+
+    /*
+     * Validate the total buffer size.
+     * The total size of the header plus the pointer-offset array and the
+     * provided buffer, together with the alignment padding for each argument,
+     * must be less than MAXLONG aligned to 4-byte boundary.
+     */
+    MaximumSize = (MAXLONG & ~3) - FIELD_OFFSET(CSR_CAPTURE_BUFFER, 
PointerOffsetsArray);
+    if (OffsetsArraySize >= MaximumSize)
+        return NULL;
+    MaximumSize -= OffsetsArraySize;
+    if (BufferSize >= MaximumSize)
+        return NULL;
+    MaximumSize -= BufferSize;
+    if ((ArgumentCount * 3) + 3 >= MaximumSize)
+        return NULL;
 
     /* Add the size of the header and of the pointer-offset array */
     BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
-                    (ArgumentCount * sizeof(ULONG_PTR));
+                    OffsetsArraySize;
 
     /* Add the size of the alignment padding for each argument */
     BufferSize += ArgumentCount * 3;
@@ -113,13 +135,12 @@ CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
     CaptureBuffer->Size = BufferSize;
     CaptureBuffer->PointerCount = 0;
 
-    /* Initialize all the offsets */
-    RtlZeroMemory(CaptureBuffer->PointerOffsetsArray,
-                  ArgumentCount * sizeof(ULONG_PTR));
+    /* Initialize the pointer-offset array */
+    RtlZeroMemory(CaptureBuffer->PointerOffsetsArray, OffsetsArraySize);
 
     /* Point to the start of the free buffer */
     CaptureBuffer->BufferEnd = 
(PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
-                                       ArgumentCount * sizeof(ULONG_PTR));
+                                       OffsetsArraySize);
 
     /* Return the address of the buffer */
     return CaptureBuffer;
diff --git a/dll/ntdll/csr/connect.c b/dll/ntdll/csr/connect.c
index 213b48b9457..f9d007b701f 100644
--- a/dll/ntdll/csr/connect.c
+++ b/dll/ntdll/csr/connect.c
@@ -407,7 +407,7 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
             ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
                 ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
 
-            /* Lock the buffer. */
+            /* Lock the buffer */
             CaptureBuffer->BufferEnd = NULL;
 
             /*

Reply via email to