diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 2ca013b833b..b207fb95353 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -1503,12 +1503,15 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN ULONG Length, OUT PULONG UnsafeResultLength) { + KPROCESSOR_MODE PreviousMode; ULONG ResultLength; PVOID SystemInformation; - NTSTATUS Status; NTSTATUS FStatus; PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + /* DPRINT("NtQuerySystemInformation Start. Class:%d\n", SystemInformationClass ); @@ -1554,22 +1557,28 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, return(Status); } }*/ - if (UnsafeResultLength != NULL) + if (NT_SUCCESS(FStatus) && UnsafeResultLength != NULL) { - /*if (ExGetPreviousMode() == KernelMode) - { - *UnsafeResultLength = ResultLength; - } - else - {*/ - Status = MmCopyToCaller(UnsafeResultLength, - &ResultLength, - sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - /*}*/ + if (PreviousMode != KernelMode) + { + FStatus = STATUS_SUCCESS; + _SEH_TRY + { + ProbeForWrite(UnsafeResultLength, + sizeof(ULONG), + sizeof(ULONG)); + *UnsafeResultLength = ResultLength; + } + _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) + { + FStatus = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + *UnsafeResultLength = ResultLength; + } } return(FStatus); } diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index dd10b6dbf30..904ed694b48 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -566,10 +566,6 @@ NTSTATUS MiZeroPage(PFN_TYPE Page); /* memsafe.s *****************************************************************/ -NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count); - -NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count); - PVOID FASTCALL MmSafeReadPtr(PVOID Source); /* pageop.c ******************************************************************/ @@ -765,14 +761,6 @@ NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process); NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process); -NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG NumberOfBytes); -NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG NumberOfBytes); - -NTSTATUS STDCALL -MmCopyFromCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes); -NTSTATUS STDCALL -MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes); - VOID MmDeleteVirtualMapping(struct _EPROCESS* Process, PVOID Address, BOOL FreePage, diff --git a/reactos/ntoskrnl/io/file.c b/reactos/ntoskrnl/io/file.c index c8fd044ddc6..be2be1478c0 100644 --- a/reactos/ntoskrnl/io/file.c +++ b/reactos/ntoskrnl/io/file.c @@ -2809,13 +2809,45 @@ NtSetInformationFile(HANDLE FileHandle, KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); BOOLEAN Failed = FALSE; - ASSERT(IoStatusBlock != NULL); - ASSERT(FileInformation != NULL); - DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d " "Class %d)\n", FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + if (IoStatusBlock != NULL) + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + } + + if (Length != 0) + { + ProbeForRead(FileInformation, + Length, + 1); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + ASSERT(IoStatusBlock != NULL); + ASSERT(FileInformation != NULL); + } + /* Get the file object from the file handle */ Status = ObReferenceObjectByHandle(FileHandle, 0, @@ -2940,13 +2972,43 @@ NtSetInformationFile(HANDLE FileHandle, Length, TAG_SYSB))) { - IoFreeIrp(Irp); - ObDereferenceObject(FileObject); - return STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INSUFFICIENT_RESOURCES; + goto failfreeirp; } /* Copy the data inside */ - MmSafeCopyFromUser(Irp->AssociatedIrp.SystemBuffer, FileInformation, Length); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + /* no need to probe again */ + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + FileInformation, + Length); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, + TAG_SYSB); + Irp->AssociatedIrp.SystemBuffer = NULL; +failfreeirp: + IoFreeIrp(Irp); + ObDereferenceObject(FileObject); + return Status; + } + } + else + { + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + FileInformation, + Length); + } /* Set up the IRP */ Irp->Tail.Overlay.OriginalFileObject = FileObject; diff --git a/reactos/ntoskrnl/io/vpb.c b/reactos/ntoskrnl/io/vpb.c index b16186bffe6..9256f1cc8b8 100644 --- a/reactos/ntoskrnl/io/vpb.c +++ b/reactos/ntoskrnl/io/vpb.c @@ -86,17 +86,49 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle, PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; PIRP Irp; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION StackPtr; PVOID SystemBuffer; KPROCESSOR_MODE PreviousMode; - ASSERT(IoStatusBlock != NULL); - ASSERT(FsInformation != NULL); - DPRINT("FsInformation %p\n", FsInformation); PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + if (IoStatusBlock != NULL) + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + } + + if (Length != 0) + { + ProbeForWrite(FsInformation, + Length, + 1); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + ASSERT(IoStatusBlock != NULL); + ASSERT(FsInformation != NULL); + } Status = ObReferenceObjectByHandle(FileHandle, 0, /* FIXME - depends on the information class! */ @@ -165,10 +197,18 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle, if (NT_SUCCESS(Status)) { - DPRINT("Information %lu\n", IoStatusBlock->Information); - MmSafeCopyToUser(FsInformation, - SystemBuffer, - IoStatusBlock->Information); + _SEH_TRY + { + DPRINT("Information %lu\n", IoStatusBlock->Information); + RtlCopyMemory(FsInformation, + SystemBuffer, + IoStatusBlock->Information); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } ExFreePool(SystemBuffer); @@ -276,10 +316,42 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, PVOID SystemBuffer; KPROCESSOR_MODE PreviousMode; - ASSERT(IoStatusBlock != NULL); - ASSERT(FsInformation != NULL); - PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + if (IoStatusBlock != NULL) + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + } + + if (Length != 0) + { + ProbeForRead(FsInformation, + Length, + 1); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + ASSERT(IoStatusBlock != NULL); + ASSERT(FsInformation != NULL); + } Status = ObReferenceObjectByHandle(FileHandle, FILE_WRITE_ATTRIBUTES, @@ -306,14 +378,41 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, TAG_SYSB); if (SystemBuffer == NULL) { - IoFreeIrp(Irp); - ObDereferenceObject(FileObject); - return(STATUS_INSUFFICIENT_RESOURCES); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto failfreeirp; } - MmSafeCopyFromUser(SystemBuffer, - FsInformation, - Length); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + /* no need to probe again */ + RtlCopyMemory(SystemBuffer, + FsInformation, + Length); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(SystemBuffer, + TAG_SYSB); +failfreeirp: + IoFreeIrp(Irp); + ObDereferenceObject(FileObject); + return Status; + } + } + else + { + RtlCopyMemory(SystemBuffer, + FsInformation, + Length); + } /* Trigger FileObject/Event dereferencing */ Irp->Tail.Overlay.OriginalFileObject = FileObject; @@ -343,7 +442,15 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, PreviousMode, FALSE, NULL); - Status = IoStatusBlock->Status; + _SEH_TRY + { + Status = IoStatusBlock->Status; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } ExFreePool(SystemBuffer); diff --git a/reactos/ntoskrnl/kdbg/i386/i386-dis.c b/reactos/ntoskrnl/kdbg/i386/i386-dis.c index c6773ebc1a7..a983a16d59c 100644 --- a/reactos/ntoskrnl/kdbg/i386/i386-dis.c +++ b/reactos/ntoskrnl/kdbg/i386/i386-dis.c @@ -47,8 +47,7 @@ extern void DbgPrint(const char *format, ...); extern unsigned int KdbSymPrintAddress(void* address); struct disassemble_info; -#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size) -extern long MmSafeCopyFromUser(void *Dest, void *Src, unsigned long NumberOfBytes); +extern long KdbpSafeReadMemory(void*, void*, unsigned int); int diff --git a/reactos/ntoskrnl/kdbg/kdb.c b/reactos/ntoskrnl/kdbg/kdb.c index 41dd9fe30eb..bfd07182e2e 100644 --- a/reactos/ntoskrnl/kdbg/kdb.c +++ b/reactos/ntoskrnl/kdbg/kdb.c @@ -1549,3 +1549,53 @@ KdbpGetCommandLineSettings(PCHAR p1) p1 = p2; } } + +NTSTATUS +KdbpSafeReadMemory(OUT PVOID Dest, + IN PVOID Src, + IN ULONG Bytes) +{ + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForRead(Src, + Bytes, + 1); + RtlCopyMemory(Dest, + Src, + Bytes); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + return Status; +} + +NTSTATUS +KdbpSafeWriteMemory(OUT PVOID Dest, + IN PVOID Src, + IN ULONG Bytes) +{ + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForWrite(Dest, + Bytes, + 1); + RtlCopyMemory(Dest, + Src, + Bytes); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + return Status; +} diff --git a/reactos/ntoskrnl/kdbg/kdb.h b/reactos/ntoskrnl/kdbg/kdb.h index 72a8fd5c0f1..ff30acc0b48 100644 --- a/reactos/ntoskrnl/kdbg/kdb.h +++ b/reactos/ntoskrnl/kdbg/kdb.h @@ -237,8 +237,15 @@ KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, BOOLEAN FirstChance); /* other functions */ -#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size) -#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size) +NTSTATUS +KdbpSafeReadMemory(OUT PVOID Dest, + IN PVOID Src, + IN ULONG Bytes); + +NTSTATUS +KdbpSafeWriteMemory(OUT PVOID Dest, + IN PVOID Src, + IN ULONG Bytes); #define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard(ScanCode, 0) CHAR diff --git a/reactos/ntoskrnl/ke/catch.c b/reactos/ntoskrnl/ke/catch.c index 39c89273ed7..56a552d79c1 100644 --- a/reactos/ntoskrnl/ke/catch.c +++ b/reactos/ntoskrnl/ke/catch.c @@ -100,7 +100,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, ULONG CDest; char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */ PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); - NTSTATUS StatusOfCopy; + NTSTATUS Status = STATUS_SUCCESS; /* Enter Debugger if available */ Action = KdpEnterDebuggerException(ExceptionRecord, @@ -130,12 +130,23 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); /* Copy Stack */ - StatusOfCopy = MmCopyToCaller(pNewUserStack, - temp_space, - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); + _SEH_TRY + { + ProbeForWrite(pNewUserStack, + 12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT), + 1); + RtlCopyMemory(pNewUserStack, + temp_space, + 12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; /* Check for success */ - if (NT_SUCCESS(StatusOfCopy)) + if (NT_SUCCESS(Status)) { /* Set new Stack Pointer */ Tf->Esp = (ULONG)pNewUserStack; diff --git a/reactos/ntoskrnl/ke/i386/usertrap.c b/reactos/ntoskrnl/ke/i386/usertrap.c index 097a0181224..5264f752df2 100644 --- a/reactos/ntoskrnl/ke/i386/usertrap.c +++ b/reactos/ntoskrnl/ke/i386/usertrap.c @@ -25,7 +25,7 @@ print_user_address(PVOID address) PPEB Peb = NULL; ULONG_PTR RelativeAddress; PPEB_LDR_DATA Ldr; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; CurrentProcess = PsGetCurrentProcess(); if (NULL != CurrentProcess) @@ -39,7 +39,17 @@ print_user_address(PVOID address) return(TRUE); } - Status = MmSafeCopyFromUser(&Ldr, &Peb->Ldr, sizeof(PPEB_LDR_DATA)); + _SEH_TRY + { + RtlCopyMemory(&Ldr, + &Peb->Ldr, + sizeof(PPEB_LDR_DATA)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { DbgPrint("<%x>", address); diff --git a/reactos/ntoskrnl/ke/i386/vdm.c b/reactos/ntoskrnl/ke/i386/vdm.c index 59c620c36dc..cca19c957ea 100644 --- a/reactos/ntoskrnl/ke/i386/vdm.c +++ b/reactos/ntoskrnl/ke/i386/vdm.c @@ -44,42 +44,64 @@ NtEarlyInitVdm(VOID) NTSTATUS STDCALL NtVdmControl(ULONG ControlCode, PVOID ControlData) { - switch (ControlCode) + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) { - case 0: - memcpy(ControlData, OrigIVT, 1024); - break; - - case 1: - memcpy(ControlData, OrigBDA, 256); - break; - - case 2: + _SEH_TRY { - KV86M_REGISTERS V86Registers; - ULONG ret; + switch (ControlCode) + { + case 0: + ProbeForWrite(ControlData, + 1024, + 1); + memcpy(ControlData, OrigIVT, 1024); + break; - ret = MmCopyFromCaller(&V86Registers, - ControlData, - sizeof(KV86M_REGISTERS)); - if(!NT_SUCCESS(ret)) return ret; + case 1: + ProbeForWrite(ControlData, + 256, + 1); + memcpy(ControlData, OrigBDA, 256); + break; - /* FIXME: This should use ->VdmObjects */ - KeGetCurrentProcess()->Unused = 1; - Ki386RetToV86Mode(&V86Registers, &V86Registers); + case 2: + { + KV86M_REGISTERS V86Registers; + + ProbeForWrite(ControlData, + sizeof(KV86M_REGISTERS), + 1); + memcpy(&V86Registers, + ControlData, + sizeof(KV86M_REGISTERS)); - /* FIXME: This should use ->VdmObjects */ - KeGetCurrentProcess()->Unused = 0; + /* FIXME: This should use ->VdmObjects */ + KeGetCurrentProcess()->Unused = 1; + Ki386RetToV86Mode(&V86Registers, &V86Registers); - ret = MmCopyToCaller(ControlData, - &V86Registers, - sizeof(KV86M_REGISTERS)); - if(!NT_SUCCESS(ret)) return ret; - - break; + /* FIXME: This should use ->VdmObjects */ + KeGetCurrentProcess()->Unused = 0; + + memcpy(ControlData, + &V86Registers, + sizeof(KV86M_REGISTERS)); + break; + } + } } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } - return(STATUS_SUCCESS); + + return Status; } /* EOF */ diff --git a/reactos/ntoskrnl/lpc/connect.c b/reactos/ntoskrnl/lpc/connect.c index 6020915f7eb..35ff36f5184 100644 --- a/reactos/ntoskrnl/lpc/connect.c +++ b/reactos/ntoskrnl/lpc/connect.c @@ -255,21 +255,72 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, PSECTION_OBJECT SectionObject; LARGE_INTEGER SectionOffset; PEPORT ConnectedPort; - NTSTATUS Status; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; PEPORT NamedPort; + + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(UnsafeConnectedPortHandle, + sizeof(HANDLE), + sizeof(ULONG)); + if (UnsafeMaximumMessageSize != NULL) + { + ProbeForWrite(UnsafeMaximumMessageSize, + sizeof(ULONG), + sizeof(ULONG)); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } /* * Copy in write map and partially validate. */ if (UnsafeWriteMap != NULL) { - Status = MmCopyFromCaller(&WriteMap, - UnsafeWriteMap, - sizeof(LPC_SECTION_WRITE)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(UnsafeWriteMap, + sizeof(LPC_SECTION_WRITE), + 1); + RtlCopyMemory(&WriteMap, + UnsafeWriteMap, + sizeof(LPC_SECTION_WRITE)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + RtlCopyMemory(&WriteMap, + UnsafeWriteMap, + sizeof(LPC_SECTION_WRITE)); + } + if (WriteMap.Length != sizeof(LPC_SECTION_WRITE)) { return(STATUS_INVALID_PARAMETER_4); @@ -291,34 +342,69 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, } else { - if (ExGetPreviousMode() == KernelMode) - { - ConnectDataLength = *UnsafeConnectDataLength; - ConnectData = UnsafeConnectData; - } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForRead(UnsafeConnectDataLength, + sizeof(ULONG), + 1); + ConnectDataLength = *UnsafeConnectDataLength; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } else - { - Status = MmCopyFromCaller(&ConnectDataLength, - UnsafeConnectDataLength, - sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength); - if (ConnectData == NULL && ConnectDataLength != 0) - { - return(STATUS_NO_MEMORY); - } - Status = MmCopyFromCaller(ConnectData, - UnsafeConnectData, - ConnectDataLength); - if (!NT_SUCCESS(Status)) - { - ExFreePool(ConnectData); - return(Status); - } - } + { + ConnectDataLength = *UnsafeConnectDataLength; + } + + if (ConnectDataLength != 0) + { + ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength); + if (ConnectData == NULL) + { + return(STATUS_NO_MEMORY); + } + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(UnsafeConnectData, + ConnectDataLength, + 1); + RtlCopyMemory(ConnectData, + UnsafeConnectData, + ConnectDataLength); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + ExFreePool(ConnectData); + return Status; + } + } + else + { + RtlCopyMemory(ConnectData, + UnsafeConnectData, + ConnectDataLength); + } + } } /* @@ -387,16 +473,30 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, /* FIXME: Again, check what NT does here. */ if (UnsafeConnectDataLength != NULL) { - if (ExGetPreviousMode() != KernelMode) + if (PreviousMode != KernelMode) { - MmCopyToCaller(UnsafeConnectData, - ConnectData, - ConnectDataLength); - ExFreePool(ConnectData); + _SEH_TRY + { + RtlCopyMemory(UnsafeConnectData, + ConnectData, + ConnectDataLength); + *UnsafeConnectDataLength = ConnectDataLength; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } - MmCopyToCaller(UnsafeConnectDataLength, - &ConnectDataLength, - sizeof(ULONG)); + else + { + RtlCopyMemory(UnsafeConnectData, + ConnectData, + ConnectDataLength); + *UnsafeConnectDataLength = ConnectDataLength; + } + + ExFreePool(ConnectData); } return(Status); } @@ -415,28 +515,52 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, /* * Copy the data back to the caller. */ - if (ExGetPreviousMode() != KernelMode) + + if (UnsafeConnectDataLength != NULL) { - if (UnsafeConnectDataLength != NULL) + if (PreviousMode != KernelMode) { - Status = MmCopyToCaller(UnsafeConnectDataLength, - &ConnectDataLength, - sizeof(ULONG)); + _SEH_TRY + { + *UnsafeConnectDataLength = ConnectDataLength; + + if (ConnectData != NULL) + { + RtlCopyMemory(UnsafeConnectData, + ConnectData, + ConnectDataLength); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) { - return(Status); + if (ConnectData != NULL) + { + ExFreePool(ConnectData); + } + return(Status); } } - if (UnsafeConnectData != NULL && ConnectData != NULL) + else + { + *UnsafeConnectDataLength = ConnectDataLength; + + if (ConnectData != NULL) + { + RtlCopyMemory(UnsafeConnectData, + ConnectData, + ConnectDataLength); + } + } + + if (ConnectData != NULL) { - Status = MmCopyToCaller(UnsafeConnectData, - ConnectData, - ConnectDataLength); ExFreePool(ConnectData); - if (!NT_SUCCESS(Status)) - { - return(Status); - } } } Status = ObInsertObject(ConnectedPort, @@ -449,42 +573,65 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, { return(Status); } - Status = MmCopyToCaller(UnsafeConnectedPortHandle, - &ConnectedPortHandle, - sizeof(HANDLE)); - if (!NT_SUCCESS(Status)) + + if (PreviousMode != KernelMode) { - return(Status); - } - if (UnsafeWriteMap != NULL) - { - Status = MmCopyToCaller(UnsafeWriteMap, - &WriteMap, - sizeof(LPC_SECTION_WRITE)); + _SEH_TRY + { + *UnsafeConnectedPortHandle = ConnectedPortHandle; + + if (UnsafeWriteMap != NULL) + { + RtlCopyMemory(UnsafeWriteMap, + &WriteMap, + sizeof(LPC_SECTION_WRITE)); + } + + if (UnsafeReadMap != NULL) + { + RtlCopyMemory(UnsafeReadMap, + &ReadMap, + sizeof(LPC_SECTION_READ)); + } + + if (UnsafeMaximumMessageSize != NULL) + { + *UnsafeMaximumMessageSize = MaximumMessageSize; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + return Status; + } } - if (UnsafeReadMap != NULL) + else { - Status = MmCopyToCaller(UnsafeReadMap, - &ReadMap, - sizeof(LPC_SECTION_READ)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - if (UnsafeMaximumMessageSize != NULL) - { - Status = MmCopyToCaller(UnsafeMaximumMessageSize, - &MaximumMessageSize, - sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + *UnsafeConnectedPortHandle = ConnectedPortHandle; + + if (UnsafeWriteMap != NULL) + { + RtlCopyMemory(UnsafeWriteMap, + &WriteMap, + sizeof(LPC_SECTION_WRITE)); + } + + if (UnsafeReadMap != NULL) + { + RtlCopyMemory(UnsafeReadMap, + &ReadMap, + sizeof(LPC_SECTION_READ)); + } + + if (UnsafeMaximumMessageSize != NULL) + { + *UnsafeMaximumMessageSize = MaximumMessageSize; + } } /* diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c index 45db8dad56e..b3c7af88764 100644 --- a/reactos/ntoskrnl/lpc/reply.c +++ b/reactos/ntoskrnl/lpc/reply.c @@ -141,16 +141,39 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, OUT PLPC_MESSAGE LpcMessage, IN PLARGE_INTEGER Timeout) { - NTSTATUS Status; PEPORT Port; KIRQL oldIrql; PQUEUEDMESSAGE Request; BOOLEAN Disconnected; LARGE_INTEGER to; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, " "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(LpcMessage, + sizeof(LPC_MESSAGE), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + Status = ObReferenceObjectByHandle(PortHandle, PORT_ALL_ACCESS, LpcPortObjectType, @@ -238,18 +261,64 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, memcpy(&Header, &Request->Message, sizeof(LPC_MESSAGE)); Header.DataSize = CRequest->ConnectDataLength; Header.MessageSize = Header.DataSize + sizeof(LPC_MESSAGE); - Status = MmCopyToCaller(LpcMessage, &Header, sizeof(LPC_MESSAGE)); - if (NT_SUCCESS(Status)) - { - Status = MmCopyToCaller((PVOID)(LpcMessage + 1), - CRequest->ConnectData, - CRequest->ConnectDataLength); - } + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite((PVOID)(LpcMessage + 1), + CRequest->ConnectDataLength, + 1); + + RtlCopyMemory(LpcMessage, + &Header, + sizeof(LPC_MESSAGE)); + RtlCopyMemory((PVOID)(LpcMessage + 1), + CRequest->ConnectData, + CRequest->ConnectDataLength); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + RtlCopyMemory(LpcMessage, + &Header, + sizeof(LPC_MESSAGE)); + RtlCopyMemory((PVOID)(LpcMessage + 1), + CRequest->ConnectData, + CRequest->ConnectDataLength); + } } else { - Status = MmCopyToCaller(LpcMessage, &Request->Message, - Request->Message.MessageSize); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(LpcMessage, + Request->Message.MessageSize, + 1); + + RtlCopyMemory(LpcMessage, + &Request->Message, + Request->Message.MessageSize); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + RtlCopyMemory(LpcMessage, + &Request->Message, + Request->Message.MessageSize); + } } if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/lpc/send.c b/reactos/ntoskrnl/lpc/send.c index 6fa0a0721ad..b1b8abbf411 100644 --- a/reactos/ntoskrnl/lpc/send.c +++ b/reactos/ntoskrnl/lpc/send.c @@ -219,12 +219,43 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle, { PETHREAD CurrentThread; struct _KPROCESS *AttachedProcess; - NTSTATUS Status; PEPORT Port; PQUEUEDMESSAGE Message; KIRQL oldIrql; PLPC_MESSAGE LpcRequest; - USHORT LpcRequestMessageSize; + USHORT LpcRequestMessageSize = 0, LpcRequestDataSize = 0; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForRead(UnsafeLpcRequest, + sizeof(LPC_MESSAGE), + 1); + ProbeForWrite(UnsafeLpcReply, + sizeof(LPC_MESSAGE), + 1); + LpcRequestMessageSize = UnsafeLpcRequest->MessageSize; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + LpcRequestMessageSize = UnsafeLpcRequest->MessageSize; + } DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, " "LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply); @@ -261,18 +292,6 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle, KeDetachProcess(); } - Status = MmCopyFromCaller(&LpcRequestMessageSize, - &UnsafeLpcRequest->MessageSize, - sizeof(USHORT)); - if (!NT_SUCCESS(Status)) - { - if (NULL != AttachedProcess) - { - KeAttachProcess(AttachedProcess); - } - ObDereferenceObject(Port); - return(Status); - } if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA)) { if (NULL != AttachedProcess) @@ -292,19 +311,42 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle, ObDereferenceObject(Port); return(STATUS_NO_MEMORY); } - Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest, - LpcRequestMessageSize); - if (!NT_SUCCESS(Status)) + if (PreviousMode != KernelMode) { - ExFreePool(LpcRequest); - if (NULL != AttachedProcess) + _SEH_TRY { - KeAttachProcess(AttachedProcess); + RtlCopyMemory(LpcRequest, + UnsafeLpcRequest, + LpcRequestMessageSize); + LpcRequestMessageSize = LpcRequest->MessageSize; + LpcRequestDataSize = LpcRequest->DataSize; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + ExFreePool(LpcRequest); + if (NULL != AttachedProcess) + { + KeAttachProcess(AttachedProcess); + } + ObDereferenceObject(Port); + return(Status); } - ObDereferenceObject(Port); - return(Status); } - LpcRequestMessageSize = LpcRequest->MessageSize; + else + { + RtlCopyMemory(LpcRequest, + UnsafeLpcRequest, + LpcRequestMessageSize); + LpcRequestMessageSize = LpcRequest->MessageSize; + LpcRequestDataSize = LpcRequest->DataSize; + } + if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA)) { ExFreePool(LpcRequest); @@ -315,7 +357,7 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle, ObDereferenceObject(Port); return(STATUS_PORT_MESSAGE_TOO_LONG); } - if (LpcRequest->DataSize != (LpcRequest->MessageSize - sizeof(LPC_MESSAGE))) + if (LpcRequestDataSize != (LpcRequestMessageSize - sizeof(LPC_MESSAGE))) { ExFreePool(LpcRequest); if (NULL != AttachedProcess) @@ -366,8 +408,26 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle, { DPRINT("Message->Message.MessageSize %d\n", Message->Message.MessageSize); - Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message, - Message->Message.MessageSize); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + RtlCopyMemory(UnsafeLpcReply, + &Message->Message, + Message->Message.MessageSize); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + RtlCopyMemory(UnsafeLpcReply, + &Message->Message, + Message->Message.MessageSize); + } ExFreePool(Message); } else diff --git a/reactos/ntoskrnl/mm/i386/memsafe.s b/reactos/ntoskrnl/mm/i386/memsafe.s index 6c827cf1b13..7141a09de7b 100644 --- a/reactos/ntoskrnl/mm/i386/memsafe.s +++ b/reactos/ntoskrnl/mm/i386/memsafe.s @@ -1,91 +1,7 @@ -.globl _MmSafeCopyFromUser -.globl _MmSafeCopyFromUserUnsafeStart -.globl _MmSafeCopyFromUserRestart -.globl _MmSafeCopyToUser -.globl _MmSafeCopyToUserUnsafeStart -.globl _MmSafeCopyToUserRestart .globl @MmSafeReadPtr@4 .globl _MmSafeReadPtrStart .globl _MmSafeReadPtrEnd - /* - * NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, - * ULONG NumberOfBytes) - */ -_MmSafeCopyFromUser: - pushl %ebp - movl %esp,%ebp - - pushl %esi - pushl %edi - pushl %ecx - - movl 8(%ebp),%edi - movl 12(%ebp),%esi - movl 16(%ebp),%ecx - - /* - * Default return code - */ - movl $0,%eax - -_MmSafeCopyFromUserUnsafeStart: - /* - * This is really a synthetic instruction since if we incur a - * pagefault then eax will be set to an appropiate STATUS code - */ - cld - rep movsb - -_MmSafeCopyFromUserRestart: - - popl %ecx - popl %edi - popl %esi - - popl %ebp - ret - -/*****************************************************************************/ - - /* - * NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, - * ULONG NumberOfBytes) - */ -_MmSafeCopyToUser: - pushl %ebp - movl %esp,%ebp - - pushl %esi - pushl %edi - pushl %ecx - - movl 8(%ebp),%edi - movl 12(%ebp),%esi - movl 16(%ebp),%ecx - - /* - * Default return code - */ - movl $0,%eax - -_MmSafeCopyToUserUnsafeStart: - /* - * This is really a synthetic instruction since if we incur a - * pagefault then eax will be set to an appropiate STATUS code - */ - cld - rep movsb - -_MmSafeCopyToUserRestart: - - popl %ecx - popl %edi - popl %esi - - popl %ebp - ret - /*****************************************************************************/ /* diff --git a/reactos/ntoskrnl/mm/i386/pfault.c b/reactos/ntoskrnl/mm/i386/pfault.c index 57eead27bb3..ee32c2b6897 100644 --- a/reactos/ntoskrnl/mm/i386/pfault.c +++ b/reactos/ntoskrnl/mm/i386/pfault.c @@ -16,10 +16,6 @@ /* EXTERNS *******************************************************************/ -extern VOID MmSafeCopyFromUserUnsafeStart(VOID); -extern VOID MmSafeCopyFromUserRestart(VOID); -extern VOID MmSafeCopyToUserUnsafeStart(VOID); -extern VOID MmSafeCopyToUserRestart(VOID); extern VOID MmSafeReadPtrStart(VOID); extern VOID MmSafeReadPtrEnd(VOID); @@ -76,22 +72,7 @@ NTSTATUS MmPageFault(ULONG Cs, KiDeliverApc(KernelMode, NULL, NULL); KeLowerIrql(oldIrql); } - if (!NT_SUCCESS(Status) && (Mode == KernelMode) && - ((*Eip) >= (ULONG_PTR)MmSafeCopyFromUserUnsafeStart) && - ((*Eip) <= (ULONG_PTR)MmSafeCopyFromUserRestart)) - { - (*Eip) = (ULONG_PTR)MmSafeCopyFromUserRestart; - (*Eax) = STATUS_ACCESS_VIOLATION; - return(STATUS_SUCCESS); - } - if (!NT_SUCCESS(Status) && (Mode == KernelMode) && - ((*Eip) >= (ULONG_PTR)MmSafeCopyToUserUnsafeStart) && - ((*Eip) <= (ULONG_PTR)MmSafeCopyToUserRestart)) - { - (*Eip) = (ULONG_PTR)MmSafeCopyToUserRestart; - (*Eax) = STATUS_ACCESS_VIOLATION; - return(STATUS_SUCCESS); - } + if (!NT_SUCCESS(Status) && (Mode == KernelMode) && ((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) && ((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd)) diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index dd5f0058a22..8886555270b 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -28,50 +28,6 @@ MM_STATS MmStats; /* FUNCTIONS ****************************************************************/ -NTSTATUS STDCALL -MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes) -{ - NTSTATUS Status; - - if (ExGetPreviousMode() == UserMode) - { - if (Dest >= MmSystemRangeStart) - { - return(STATUS_ACCESS_VIOLATION); - } - Status = MmSafeCopyToUser(Dest, Src, NumberOfBytes); - return(Status); - } - else - { - memcpy(Dest, Src, NumberOfBytes); - return(STATUS_SUCCESS); - } -} - -NTSTATUS STDCALL -MmCopyFromCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes) -{ - NTSTATUS Status; - - if (ExGetPreviousMode() == UserMode) - { - if (Src >= MmSystemRangeStart) - { - return(STATUS_ACCESS_VIOLATION); - } - Status = MmSafeCopyFromUser(Dest, Src, NumberOfBytes); - return(Status); - } - else - { - memcpy(Dest, Src, NumberOfBytes); - return(STATUS_SUCCESS); - } -} - - - NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) { NTSTATUS Status; diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 84cee3545d1..e0fe34b1389 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -269,9 +269,9 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle, IN ULONG Length, OUT PULONG UnsafeResultLength) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; ULONG ResultLength = 0; - KPROCESSOR_MODE PrevMode; + KPROCESSOR_MODE PreviousMode; union { MEMORY_BASIC_INFORMATION BasicInfo; @@ -284,7 +284,27 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle, VirtualMemoryInformationClass,VirtualMemoryInformation, Length,ResultLength); - PrevMode = ExGetPreviousMode(); + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode && UnsafeResultLength != NULL) + { + _SEH_TRY + { + ProbeForWrite(UnsafeResultLength, + sizeof(ULONG), + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } if (Address >= MmSystemRangeStart) { @@ -299,19 +319,48 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle, Length, &ResultLength ); - if (NT_SUCCESS(Status) && ResultLength > 0) + if (NT_SUCCESS(Status)) { - Status = MmCopyToCaller(VirtualMemoryInformation, &VirtualMemoryInfo, ResultLength); - if (!NT_SUCCESS(Status)) - { - ResultLength = 0; - } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + if (ResultLength > 0) + { + ProbeForWrite(VirtualMemoryInformation, + ResultLength, + 1); + RtlCopyMemory(VirtualMemoryInformation, + &VirtualMemoryInfo, + ResultLength); + } + if (UnsafeResultLength != NULL) + { + *UnsafeResultLength = ResultLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + if (ResultLength > 0) + { + RtlCopyMemory(VirtualMemoryInformation, + &VirtualMemoryInfo, + ResultLength); + } + + if (UnsafeResultLength != NULL) + { + *UnsafeResultLength = ResultLength; + } + } } - if (UnsafeResultLength != NULL) - { - MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG)); - } return(Status); } @@ -384,17 +433,47 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle, OUT PULONG UnsafeOldAccessProtection) { PEPROCESS Process; - NTSTATUS Status; ULONG OldAccessProtection; - PVOID BaseAddress; - ULONG NumberOfBytesToProtect; + PVOID BaseAddress = NULL; + ULONG NumberOfBytesToProtect = 0; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(UnsafeBaseAddress, + sizeof(PVOID), + sizeof(ULONG)); + ProbeForWrite(UnsafeBaseAddress, + sizeof(ULONG), + sizeof(ULONG)); + ProbeForWrite(UnsafeOldAccessProtection, + sizeof(ULONG), + sizeof(ULONG)); - Status = MmCopyFromCaller(&BaseAddress, UnsafeBaseAddress, sizeof(PVOID)); - if (!NT_SUCCESS(Status)) - return Status; - Status = MmCopyFromCaller(&NumberOfBytesToProtect, UnsafeNumberOfBytesToProtect, sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - return Status; + BaseAddress = *UnsafeBaseAddress; + NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + BaseAddress = *UnsafeBaseAddress; + NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; + } /* (tMk 2004.II.5) in Microsoft SDK I read: * 'if this parameter is NULL or does not point to a valid variable, the function fails' @@ -424,9 +503,26 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle, ObDereferenceObject(Process); - MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection, sizeof(ULONG)); - MmCopyToCaller(UnsafeBaseAddress, &BaseAddress, sizeof(PVOID)); - MmCopyToCaller(UnsafeNumberOfBytesToProtect, &NumberOfBytesToProtect, sizeof(ULONG)); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + *UnsafeOldAccessProtection = OldAccessProtection; + *UnsafeBaseAddress = BaseAddress; + *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + *UnsafeOldAccessProtection = OldAccessProtection; + *UnsafeBaseAddress = BaseAddress; + *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect; + } return(Status); } @@ -648,18 +744,41 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL) { - NTSTATUS Status; PMDL Mdl; PVOID SystemAddress; PEPROCESS Process; ULONG OldProtection = 0; PVOID ProtectBaseAddress; ULONG ProtectNumberOfBytes; + KPROCESSOR_MODE PreviousMode; + NTSTATUS CopyStatus, Status = STATUS_SUCCESS; DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, " "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress, Buffer,NumberOfBytesToWrite); + PreviousMode = ExGetPreviousMode(); + + if (PreviousMode != KernelMode && NumberOfBytesWritten != NULL) + { + _SEH_TRY + { + ProbeForWrite(NumberOfBytesWritten, + sizeof(ULONG), + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + Status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_VM_WRITE, NULL, @@ -680,6 +799,8 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, */ ProtectBaseAddress = BaseAddress; ProtectNumberOfBytes = NumberOfBytesToWrite; + + CopyStatus = STATUS_SUCCESS; /* Write memory */ if (Process == PsGetCurrentProcess()) @@ -694,7 +815,23 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, ObDereferenceObject(Process); return Status; } - memcpy(BaseAddress, Buffer, NumberOfBytesToWrite); + + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + memcpy(BaseAddress, Buffer, NumberOfBytesToWrite); + } + _SEH_HANDLE + { + CopyStatus = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + memcpy(BaseAddress, Buffer, NumberOfBytesToWrite); + } } else { @@ -730,7 +867,22 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, KeAttachProcess(&Process->Pcb); SystemAddress = MmGetSystemAddressForMdl(Mdl); - memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + } + _SEH_HANDLE + { + CopyStatus = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + } KeDetachProcess(); @@ -758,9 +910,26 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, ObDereferenceObject(Process); if (NumberOfBytesWritten != NULL) - MmCopyToCaller(NumberOfBytesWritten, &NumberOfBytesToWrite, sizeof(ULONG)); + { + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + *NumberOfBytesWritten = NumberOfBytesToWrite; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + *NumberOfBytesWritten = NumberOfBytesToWrite; + } + } - return(STATUS_SUCCESS); + return(NT_SUCCESS(CopyStatus) ? Status : CopyStatus); } /* diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 799c71b3cf9..514da8f8522 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -688,8 +688,6 @@ MmAllocateNonCachedMemory@4 MmAllocatePagesForMdl@28 MmBuildMdlForNonPagedPool@4 MmCanFileBeTruncated@8 -;MmCopyFromCaller@12 -;MmCopyToCaller@12 MmCreateMdl@12 MmCreateSection@32 MmDbgTranslatePhysicalAddress@8 diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index cae8caef2e6..bdf17a8ece8 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -1135,7 +1135,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle, IN ULONG ThreadInformationLength) { PETHREAD Thread; - NTSTATUS Status; union { KPRIORITY Priority; @@ -1144,8 +1143,12 @@ NtSetInformationThread (IN HANDLE ThreadHandle, HANDLE Handle; PVOID Address; }u; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); if (ThreadInformationClass <= MaxThreadInfoClass && !SetInformationData[ThreadInformationClass].Implemented) @@ -1162,20 +1165,41 @@ NtSetInformationThread (IN HANDLE ThreadHandle, return STATUS_INFO_LENGTH_MISMATCH; } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForRead(ThreadInformation, + SetInformationData[ThreadInformationClass].Size, + 1); + RtlCopyMemory(&u.Priority, + ThreadInformation, + SetInformationData[ThreadInformationClass].Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + RtlCopyMemory(&u.Priority, + ThreadInformation, + SetInformationData[ThreadInformationClass].Size); + } + Status = ObReferenceObjectByHandle (ThreadHandle, THREAD_SET_INFORMATION, PsThreadType, ExGetPreviousMode (), (PVOID*)&Thread, NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status = MmCopyFromCaller(&u.Priority, - ThreadInformation, - SetInformationData[ThreadInformationClass].Size); if (NT_SUCCESS(Status)) { switch (ThreadInformationClass) @@ -1226,7 +1250,6 @@ NtQueryInformationThread (IN HANDLE ThreadHandle, OUT PULONG ReturnLength OPTIONAL) { PETHREAD Thread; - NTSTATUS Status; union { THREAD_BASIC_INFORMATION TBI; @@ -1235,8 +1258,12 @@ NtQueryInformationThread (IN HANDLE ThreadHandle, LARGE_INTEGER Count; BOOLEAN Last; }u; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); if (ThreadInformationClass <= MaxThreadInfoClass && !QueryInformationData[ThreadInformationClass].Implemented) @@ -1253,6 +1280,32 @@ NtQueryInformationThread (IN HANDLE ThreadHandle, return STATUS_INFO_LENGTH_MISMATCH; } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(ThreadInformation, + QueryInformationData[ThreadInformationClass].Size, + 1); + if (ReturnLength != NULL) + { + ProbeForWrite(ReturnLength, + sizeof(ULONG), + sizeof(ULONG)); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, PsThreadType, @@ -1311,23 +1364,41 @@ NtQueryInformationThread (IN HANDLE ThreadHandle, /* Shoult never occure if the data table is correct */ KEBUGCHECK(0); } - if (QueryInformationData[ThreadInformationClass].Size) + + if (PreviousMode != KernelMode) { - Status = MmCopyToCaller(ThreadInformation, - &u.TBI, - QueryInformationData[ThreadInformationClass].Size); - } - if (ReturnLength) - { - NTSTATUS Status2; - static ULONG Null = 0; - Status2 = MmCopyToCaller(ReturnLength, - NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null, - sizeof(ULONG)); - if (NT_SUCCESS(Status)) + _SEH_TRY { - Status = Status2; - } + if (QueryInformationData[ThreadInformationClass].Size) + { + RtlCopyMemory(ThreadInformation, + &u.TBI, + QueryInformationData[ThreadInformationClass].Size); + } + if (ReturnLength != NULL) + { + *ReturnLength = QueryInformationData[ThreadInformationClass].Size; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + if (QueryInformationData[ThreadInformationClass].Size) + { + RtlCopyMemory(ThreadInformation, + &u.TBI, + QueryInformationData[ThreadInformationClass].Size); + } + + if (ReturnLength != NULL) + { + *ReturnLength = QueryInformationData[ThreadInformationClass].Size; + } } ObDereferenceObject(Thread); diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index ad41dd456a9..8873581974c 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -2052,6 +2052,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, PVOID EndMem; ULONG uLength; ULONG i; + ULONG nTokenPrivileges = 0; KPROCESSOR_MODE PreviousMode; NTSTATUS Status = STATUS_SUCCESS; @@ -2093,6 +2094,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, ProbeForRead(TokenSource, sizeof(TOKEN_SOURCE), sizeof(ULONG)); + nTokenPrivileges = TokenPrivileges->PrivilegeCount; } _SEH_HANDLE { @@ -2105,6 +2107,10 @@ NtCreateToken(OUT PHANDLE TokenHandle, return Status; } } + else + { + nTokenPrivileges = TokenPrivileges->PrivilegeCount; + } Status = ZwAllocateLocallyUniqueId(&TokenId); if (!NT_SUCCESS(Status)) @@ -2203,14 +2209,26 @@ NtCreateToken(OUT PHANDLE TokenHandle, uLength, TAG('T', 'O', 'K', 'p')); - for (i = 0; i < TokenPrivileges->PrivilegeCount; i++) - { - Status = MmCopyFromCaller(&AccessToken->Privileges[i], - &TokenPrivileges->Privileges[i], - sizeof(LUID_AND_ATTRIBUTES)); - if (!NT_SUCCESS(Status)) - break; - } + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + RtlCopyMemory(AccessToken->Privileges, + TokenPrivileges->Privileges, + nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + RtlCopyMemory(AccessToken->Privileges, + TokenPrivileges->Privileges, + nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); + } } if (NT_SUCCESS(Status))