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

commit 4441b1cd44bbf0f16b49383759bf50a35828da6a
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Tue Dec 8 10:28:52 2020 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Feb 3 09:41:22 2021 +0100

    [NTOS:CC] Fix some tests for CcCopyRead and CcCopyWrite
    
    Most importantly: raise the right status when provided an invalid buffer.
---
 ntoskrnl/cc/copy.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/ntoskrnl/cc/copy.c b/ntoskrnl/cc/copy.c
index 357e98162e6..315e9f1f1b0 100644
--- a/ntoskrnl/cc/copy.c
+++ b/ntoskrnl/cc/copy.c
@@ -447,6 +447,26 @@ CcCanIWrite (
     return TRUE;
 }
 
+static
+int
+CcpCheckInvalidUserBuffer(PEXCEPTION_POINTERS Except, PVOID Buffer, ULONG 
Length)
+{
+    ULONG_PTR ExceptionAddress;
+    ULONG_PTR BeginAddress = (ULONG_PTR)Buffer;
+    ULONG_PTR EndAddress = (ULONG_PTR)Buffer + Length;
+
+    if (Except->ExceptionRecord->ExceptionCode != STATUS_ACCESS_VIOLATION)
+        return EXCEPTION_CONTINUE_SEARCH;
+    if (Except->ExceptionRecord->NumberParameters < 2)
+        return EXCEPTION_CONTINUE_SEARCH;
+
+    ExceptionAddress = Except->ExceptionRecord->ExceptionInformation[1];
+    if ((ExceptionAddress >= BeginAddress) && (ExceptionAddress < EndAddress))
+        return EXCEPTION_EXECUTE_HANDLER;
+
+    return EXCEPTION_CONTINUE_SEARCH;
+}
+
 /*
  * @implemented
  */
@@ -465,6 +485,7 @@ CcCopyRead (
     NTSTATUS Status;
     LONGLONG CurrentOffset;
     LONGLONG ReadEnd = FileOffset->QuadPart + Length;
+    ULONG ReadLength = 0;
 
     CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu 
Wait=%d\n",
         FileObject, FileOffset->QuadPart, Length, Wait);
@@ -480,9 +501,6 @@ CcCopyRead (
     /* Documented to ASSERT, but KMTests test this case... */
     // ASSERT((FileOffset->QuadPart + Length) <= 
SharedCacheMap->FileSize.QuadPart);
 
-    IoStatus->Status = STATUS_SUCCESS;
-    IoStatus->Information = 0;
-
     CurrentOffset = FileOffset->QuadPart;
     while(CurrentOffset < ReadEnd)
     {
@@ -506,13 +524,23 @@ CcCopyRead (
             if (CurrentOffset + VacbLength > 
SharedCacheMap->SectionSize.QuadPart)
                 CopyLength = SharedCacheMap->SectionSize.QuadPart - 
CurrentOffset;
             if (CopyLength != 0)
-                RtlCopyMemory(Buffer, (PUCHAR)Vacb->BaseAddress + VacbOffset, 
CopyLength);
+            {
+                _SEH2_TRY
+                {
+                    RtlCopyMemory(Buffer, (PUCHAR)Vacb->BaseAddress + 
VacbOffset, CopyLength);
+                }
+                
_SEH2_EXCEPT(CcpCheckInvalidUserBuffer(_SEH2_GetExceptionInformation(), Buffer, 
VacbLength))
+                {
+                    ExRaiseStatus(STATUS_INVALID_USER_BUFFER);
+                }
+                _SEH2_END;
+            }
 
             /* Zero-out the buffer tail if needed */
             if (CopyLength < VacbLength)
                 RtlZeroMemory((PUCHAR)Buffer + CopyLength, VacbLength - 
CopyLength);
 
-            IoStatus->Information += VacbLength;
+            ReadLength += VacbLength;
 
             Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
             CurrentOffset += VacbLength;
@@ -525,6 +553,9 @@ CcCopyRead (
         _SEH2_END;
     }
 
+    IoStatus->Status = STATUS_SUCCESS;
+    IoStatus->Information = ReadLength;
+
     return TRUE;
 }
 
@@ -578,7 +609,15 @@ CcCopyWrite (
                 return FALSE;
             }
 
-            RtlCopyMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + VacbOffset), 
Buffer, VacbLength);
+            _SEH2_TRY
+            {
+                RtlCopyMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + 
VacbOffset), Buffer, VacbLength);
+            }
+            
_SEH2_EXCEPT(CcpCheckInvalidUserBuffer(_SEH2_GetExceptionInformation(), Buffer, 
VacbLength))
+            {
+                ExRaiseStatus(STATUS_INVALID_USER_BUFFER);
+            }
+            _SEH2_END;
 
             Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
             CurrentOffset += VacbLength;

Reply via email to