removed MmCopyFromCaller and MmCopyToCaller and depend on SEH instead

svn path=/trunk/; revision=16691
This commit is contained in:
Thomas Bluemel 2005-07-22 20:52:31 +00:00
parent 4bfbd2cfaf
commit 9f2bf70ddb
20 changed files with 1080 additions and 430 deletions

View file

@ -1503,13 +1503,16 @@ 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)
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;
}
else
{*/
Status = MmCopyToCaller(UnsafeResultLength,
&ResultLength,
sizeof(ULONG));
if (!NT_SUCCESS(Status))
{
return(Status);
}
/*}*/
}
return(FStatus);
}

View file

@ -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,

View file

@ -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;

View file

@ -86,18 +86,50 @@ 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! */
IoFileObjectType,
@ -164,12 +196,20 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
DPRINT("Status %x\n", Status);
if (NT_SUCCESS(Status))
{
_SEH_TRY
{
DPRINT("Information %lu\n", IoStatusBlock->Information);
MmSafeCopyToUser(FsInformation,
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;
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);
PreviousMode = ExGetPreviousMode();
}
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,
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,8 +442,16 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
PreviousMode,
FALSE,
NULL);
_SEH_TRY
{
Status = IoStatusBlock->Status;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
ExFreePool(SystemBuffer);

View file

@ -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

View file

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

View file

@ -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

View file

@ -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,
_SEH_TRY
{
ProbeForWrite(pNewUserStack,
12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT),
1);
RtlCopyMemory(pNewUserStack,
temp_space,
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
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;

View file

@ -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);

View file

@ -44,25 +44,41 @@ NtEarlyInitVdm(VOID)
NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
PVOID ControlData)
{
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
if (PreviousMode != KernelMode)
{
_SEH_TRY
{
switch (ControlCode)
{
case 0:
ProbeForWrite(ControlData,
1024,
1);
memcpy(ControlData, OrigIVT, 1024);
break;
case 1:
ProbeForWrite(ControlData,
256,
1);
memcpy(ControlData, OrigBDA, 256);
break;
case 2:
{
KV86M_REGISTERS V86Registers;
ULONG ret;
ret = MmCopyFromCaller(&V86Registers,
ProbeForWrite(ControlData,
sizeof(KV86M_REGISTERS),
1);
memcpy(&V86Registers,
ControlData,
sizeof(KV86M_REGISTERS));
if(!NT_SUCCESS(ret)) return ret;
/* FIXME: This should use ->VdmObjects */
KeGetCurrentProcess()->Unused = 1;
@ -71,15 +87,21 @@ NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
/* FIXME: This should use ->VdmObjects */
KeGetCurrentProcess()->Unused = 0;
ret = MmCopyToCaller(ControlData,
memcpy(ControlData,
&V86Registers,
sizeof(KV86M_REGISTERS));
if(!NT_SUCCESS(ret)) return ret;
break;
}
}
return(STATUS_SUCCESS);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status;
}
/* EOF */

View file

@ -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,
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);
return Status;
}
}
else
{
RtlCopyMemory(&WriteMap,
UnsafeWriteMap,
sizeof(LPC_SECTION_WRITE));
}
if (WriteMap.Length != sizeof(LPC_SECTION_WRITE))
{
return(STATUS_INVALID_PARAMETER_4);
@ -291,32 +342,67 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
}
else
{
if (ExGetPreviousMode() == KernelMode)
if (PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(UnsafeConnectDataLength,
sizeof(ULONG),
1);
ConnectDataLength = *UnsafeConnectDataLength;
ConnectData = UnsafeConnectData;
}
_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);
ConnectDataLength = *UnsafeConnectDataLength;
}
if (ConnectDataLength != 0)
{
ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
if (ConnectData == NULL && ConnectDataLength != 0)
if (ConnectData == NULL)
{
return(STATUS_NO_MEMORY);
}
Status = MmCopyFromCaller(ConnectData,
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);
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,
_SEH_TRY
{
RtlCopyMemory(UnsafeConnectData,
ConnectData,
ConnectDataLength);
ExFreePool(ConnectData);
*UnsafeConnectDataLength = ConnectDataLength;
}
MmCopyToCaller(UnsafeConnectDataLength,
&ConnectDataLength,
sizeof(ULONG));
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
RtlCopyMemory(UnsafeConnectData,
ConnectData,
ConnectDataLength);
*UnsafeConnectDataLength = ConnectDataLength;
}
ExFreePool(ConnectData);
}
return(Status);
}
@ -415,29 +515,53 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
/*
* Copy the data back to the caller.
*/
if (ExGetPreviousMode() != KernelMode)
{
if (UnsafeConnectDataLength != NULL)
{
Status = MmCopyToCaller(UnsafeConnectDataLength,
&ConnectDataLength,
sizeof(ULONG));
if (!NT_SUCCESS(Status))
if (PreviousMode != KernelMode)
{
return(Status);
}
}
if (UnsafeConnectData != NULL && ConnectData != NULL)
_SEH_TRY
{
Status = MmCopyToCaller(UnsafeConnectData,
*UnsafeConnectDataLength = ConnectDataLength;
if (ConnectData != NULL)
{
RtlCopyMemory(UnsafeConnectData,
ConnectData,
ConnectDataLength);
ExFreePool(ConnectData);
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
if (ConnectData != NULL)
{
ExFreePool(ConnectData);
}
return(Status);
}
}
else
{
*UnsafeConnectDataLength = ConnectDataLength;
if (ConnectData != NULL)
{
RtlCopyMemory(UnsafeConnectData,
ConnectData,
ConnectDataLength);
}
}
if (ConnectData != NULL)
{
ExFreePool(ConnectData);
}
}
Status = ObInsertObject(ConnectedPort,
NULL,
@ -449,41 +573,64 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
{
return(Status);
}
Status = MmCopyToCaller(UnsafeConnectedPortHandle,
&ConnectedPortHandle,
sizeof(HANDLE));
if (!NT_SUCCESS(Status))
if (PreviousMode != KernelMode)
{
return(Status);
}
_SEH_TRY
{
*UnsafeConnectedPortHandle = ConnectedPortHandle;
if (UnsafeWriteMap != NULL)
{
Status = MmCopyToCaller(UnsafeWriteMap,
RtlCopyMemory(UnsafeWriteMap,
&WriteMap,
sizeof(LPC_SECTION_WRITE));
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
if (UnsafeReadMap != NULL)
{
Status = MmCopyToCaller(UnsafeReadMap,
RtlCopyMemory(UnsafeReadMap,
&ReadMap,
sizeof(LPC_SECTION_READ));
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
if (UnsafeMaximumMessageSize != NULL)
{
Status = MmCopyToCaller(UnsafeMaximumMessageSize,
&MaximumMessageSize,
sizeof(ULONG));
*UnsafeMaximumMessageSize = MaximumMessageSize;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
return(Status);
return Status;
}
}
else
{
*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;
}
}

View file

@ -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,19 +261,65 @@ 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))
if (PreviousMode != KernelMode)
{
Status = MmCopyToCaller((PVOID)(LpcMessage + 1),
_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,
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))
{
/*

View file

@ -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,8 +311,22 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
ObDereferenceObject(Port);
return(STATUS_NO_MEMORY);
}
Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest,
if (PreviousMode != KernelMode)
{
_SEH_TRY
{
RtlCopyMemory(LpcRequest,
UnsafeLpcRequest,
LpcRequestMessageSize);
LpcRequestMessageSize = LpcRequest->MessageSize;
LpcRequestDataSize = LpcRequest->DataSize;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
ExFreePool(LpcRequest);
@ -304,7 +337,16 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
ObDereferenceObject(Port);
return(Status);
}
}
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,
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

View file

@ -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
/*****************************************************************************/
/*

View file

@ -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))

View file

@ -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;

View file

@ -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))
if (PreviousMode != KernelMode)
{
ResultLength = 0;
_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)
{
MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
*UnsafeResultLength = ResultLength;
}
}
}
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));
BaseAddress = *UnsafeBaseAddress;
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
Status = MmCopyFromCaller(&BaseAddress, UnsafeBaseAddress, sizeof(PVOID));
if (!NT_SUCCESS(Status))
return Status;
Status = MmCopyFromCaller(&NumberOfBytesToProtect, UnsafeNumberOfBytesToProtect, sizeof(ULONG));
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,
@ -681,6 +800,8 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
ProtectBaseAddress = BaseAddress;
ProtectNumberOfBytes = NumberOfBytesToWrite;
CopyStatus = STATUS_SUCCESS;
/* Write memory */
if (Process == PsGetCurrentProcess())
{
@ -694,8 +815,24 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
ObDereferenceObject(Process);
return Status;
}
if (PreviousMode != KernelMode)
{
_SEH_TRY
{
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
}
_SEH_HANDLE
{
CopyStatus = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
}
}
else
{
/* Create MDL describing the source buffer. */
@ -730,7 +867,22 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
KeAttachProcess(&Process->Pcb);
SystemAddress = MmGetSystemAddressForMdl(Mdl);
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);
}
/*

View file

@ -688,8 +688,6 @@ MmAllocateNonCachedMemory@4
MmAllocatePagesForMdl@28
MmBuildMdlForNonPagedPool@4
MmCanFileBeTruncated@8
;MmCopyFromCaller@12
;MmCopyToCaller@12
MmCreateMdl@12
MmCreateSection@32
MmDbgTranslatePhysicalAddress@8

View file

@ -1135,7 +1135,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
IN ULONG ThreadInformationLength)
{
PETHREAD Thread;
NTSTATUS Status;
union
{
KPRIORITY Priority;
@ -1144,9 +1143,13 @@ 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,9 +1258,13 @@ 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,22 +1364,40 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
/* Shoult never occure if the data table is correct */
KEBUGCHECK(0);
}
if (PreviousMode != KernelMode)
{
_SEH_TRY
{
if (QueryInformationData[ThreadInformationClass].Size)
{
Status = MmCopyToCaller(ThreadInformation,
RtlCopyMemory(ThreadInformation,
&u.TBI,
QueryInformationData[ThreadInformationClass].Size);
}
if (ReturnLength)
if (ReturnLength != NULL)
{
NTSTATUS Status2;
static ULONG Null = 0;
Status2 = MmCopyToCaller(ReturnLength,
NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
sizeof(ULONG));
if (NT_SUCCESS(Status))
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
}
}
_SEH_HANDLE
{
Status = Status2;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
if (QueryInformationData[ThreadInformationClass].Size)
{
RtlCopyMemory(ThreadInformation,
&u.TBI,
QueryInformationData[ThreadInformationClass].Size);
}
if (ReturnLength != NULL)
{
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
}
}

View file

@ -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,13 +2209,25 @@ NtCreateToken(OUT PHANDLE TokenHandle,
uLength,
TAG('T', 'O', 'K', 'p'));
for (i = 0; i < TokenPrivileges->PrivilegeCount; i++)
if (PreviousMode != KernelMode)
{
Status = MmCopyFromCaller(&AccessToken->Privileges[i],
&TokenPrivileges->Privileges[i],
sizeof(LUID_AND_ATTRIBUTES));
if (!NT_SUCCESS(Status))
break;
_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));
}
}