[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;
}
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;