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