[NTOS:CC] Fix some tests for CcCopyRead and CcCopyWrite

Most importantly: raise the right status when provided an invalid buffer.
This commit is contained in:
Jérôme Gardou 2020-12-08 10:28:52 +01:00
parent aab24ed1b1
commit 4441b1cd44

View file

@ -447,6 +447,26 @@ CcCanIWrite (
return TRUE; 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 * @implemented
*/ */
@ -465,6 +485,7 @@ CcCopyRead (
NTSTATUS Status; NTSTATUS Status;
LONGLONG CurrentOffset; LONGLONG CurrentOffset;
LONGLONG ReadEnd = FileOffset->QuadPart + Length; LONGLONG ReadEnd = FileOffset->QuadPart + Length;
ULONG ReadLength = 0;
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d\n", CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d\n",
FileObject, FileOffset->QuadPart, Length, Wait); FileObject, FileOffset->QuadPart, Length, Wait);
@ -480,9 +501,6 @@ CcCopyRead (
/* Documented to ASSERT, but KMTests test this case... */ /* Documented to ASSERT, but KMTests test this case... */
// ASSERT((FileOffset->QuadPart + Length) <= SharedCacheMap->FileSize.QuadPart); // ASSERT((FileOffset->QuadPart + Length) <= SharedCacheMap->FileSize.QuadPart);
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = 0;
CurrentOffset = FileOffset->QuadPart; CurrentOffset = FileOffset->QuadPart;
while(CurrentOffset < ReadEnd) while(CurrentOffset < ReadEnd)
{ {
@ -506,13 +524,23 @@ CcCopyRead (
if (CurrentOffset + VacbLength > SharedCacheMap->SectionSize.QuadPart) if (CurrentOffset + VacbLength > SharedCacheMap->SectionSize.QuadPart)
CopyLength = SharedCacheMap->SectionSize.QuadPart - CurrentOffset; CopyLength = SharedCacheMap->SectionSize.QuadPart - CurrentOffset;
if (CopyLength != 0) 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 */ /* Zero-out the buffer tail if needed */
if (CopyLength < VacbLength) if (CopyLength < VacbLength)
RtlZeroMemory((PUCHAR)Buffer + CopyLength, VacbLength - CopyLength); RtlZeroMemory((PUCHAR)Buffer + CopyLength, VacbLength - CopyLength);
IoStatus->Information += VacbLength; ReadLength += VacbLength;
Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength); Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
CurrentOffset += VacbLength; CurrentOffset += VacbLength;
@ -525,6 +553,9 @@ CcCopyRead (
_SEH2_END; _SEH2_END;
} }
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = ReadLength;
return TRUE; return TRUE;
} }
@ -578,7 +609,15 @@ CcCopyWrite (
return FALSE; 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); Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
CurrentOffset += VacbLength; CurrentOffset += VacbLength;