https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4441b1cd44bbf0f16b493…
commit 4441b1cd44bbf0f16b49383759bf50a35828da6a
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Tue Dec 8 10:28:52 2020 +0100
Commit: Jérôme Gardou <jerome.gardou(a)reactos.org>
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;