safely access buffers in NtReadVirtualMemory()
Modified: trunk/reactos/ntoskrnl/mm/virtual.c
_____
Modified: trunk/reactos/ntoskrnl/mm/virtual.c
--- trunk/reactos/ntoskrnl/mm/virtual.c 2005-03-14 14:30:43 UTC (rev
14061)
+++ trunk/reactos/ntoskrnl/mm/virtual.c 2005-03-14 15:22:46 UTC (rev
14062)
@@ -463,12 +463,42 @@
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead OPTIONAL)
{
- NTSTATUS Status;
PMDL Mdl;
PVOID SystemAddress;
+ KPROCESSOR_MODE PreviousMode;
PEPROCESS Process, CurrentProcess;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(Buffer,
+ NumberOfBytesToRead,
+ 1);
+ if(NumberOfBytesRead != NULL)
+ {
+ ProbeForWrite(NumberOfBytesRead,
+ sizeof(ULONG),
+ sizeof(ULONG));
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
-
DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
"Buffer %x, NumberOfBytesToRead
%d)\n",ProcessHandle,BaseAddress,
Buffer,NumberOfBytesToRead);
@@ -476,7 +506,7 @@
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_WRITE,
NULL,
- UserMode,
+ PreviousMode,
(PVOID*)(&Process),
NULL);
if (!NT_SUCCESS(Status))
@@ -488,7 +518,15 @@
if (Process == CurrentProcess)
{
- memcpy(Buffer, BaseAddress, NumberOfBytesToRead);
+ _SEH_TRY
+ {
+ RtlCopyMemory(Buffer, BaseAddress, NumberOfBytesToRead);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
else
{
@@ -500,39 +538,62 @@
ObDereferenceObject(Process);
return(STATUS_NO_MEMORY);
}
- MmProbeAndLockPages(Mdl,
- UserMode,
- IoWriteAccess);
+ _SEH_TRY
+ {
+ MmProbeAndLockPages(Mdl,
+ PreviousMode,
+ IoWriteAccess);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(NT_SUCCESS(Status))
+ {
+ KeAttachProcess(&Process->Pcb);
- KeAttachProcess(&Process->Pcb);
+ SystemAddress = MmGetSystemAddressForMdl(Mdl);
- SystemAddress = MmGetSystemAddressForMdl(Mdl);
+ Status = STATUS_SUCCESS;
+ _SEH_TRY {
+ ProbeForRead(BaseAddress, NumberOfBytesToRead, 1);
+ Status = STATUS_PARTIAL_COPY;
+ RtlCopyMemory(SystemAddress, BaseAddress,
NumberOfBytesToRead);
+ Status = STATUS_SUCCESS;
+ } _SEH_HANDLE {
+ if(Status != STATUS_PARTIAL_COPY)
+ Status = _SEH_GetExceptionCode();
+ } _SEH_END;
- Status = STATUS_SUCCESS;
- _SEH_TRY {
- ProbeForRead(BaseAddress, NumberOfBytesToRead, 1);
- Status = STATUS_PARTIAL_COPY;
- memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
- Status = STATUS_SUCCESS;
- } _SEH_HANDLE {
- if(Status != STATUS_PARTIAL_COPY)
- Status = _SEH_GetExceptionCode();
- } _SEH_END;
+ KeDetachProcess();
- KeDetachProcess();
-
- if (Mdl->MappedSystemVa != NULL)
- {
- MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+ if (Mdl->MappedSystemVa != NULL)
+ {
+ MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+ }
+ MmUnlockPages(Mdl);
}
- MmUnlockPages(Mdl);
ExFreePool(Mdl);
}
ObDereferenceObject(Process);
- if (NumberOfBytesRead)
- *NumberOfBytesRead = NumberOfBytesToRead;
+ if((NT_SUCCESS(Status) || Status == STATUS_PARTIAL_COPY) &&
+ NumberOfBytesRead != NULL)
+ {
+ _SEH_TRY
+ {
+ *NumberOfBytesRead = NumberOfBytesToRead;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+
return(Status);
}