removed MmCopyFromCaller and MmCopyToCaller and depend on SEH instead
authorThomas Bluemel <thomas@reactsoft.com>
Fri, 22 Jul 2005 20:52:31 +0000 (20:52 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Fri, 22 Jul 2005 20:52:31 +0000 (20:52 +0000)
svn path=/trunk/; revision=16691

20 files changed:
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/io/file.c
reactos/ntoskrnl/io/vpb.c
reactos/ntoskrnl/kdbg/i386/i386-dis.c
reactos/ntoskrnl/kdbg/kdb.c
reactos/ntoskrnl/kdbg/kdb.h
reactos/ntoskrnl/ke/catch.c
reactos/ntoskrnl/ke/i386/usertrap.c
reactos/ntoskrnl/ke/i386/vdm.c
reactos/ntoskrnl/lpc/connect.c
reactos/ntoskrnl/lpc/reply.c
reactos/ntoskrnl/lpc/send.c
reactos/ntoskrnl/mm/i386/memsafe.s
reactos/ntoskrnl/mm/i386/pfault.c
reactos/ntoskrnl/mm/mm.c
reactos/ntoskrnl/mm/virtual.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ps/query.c
reactos/ntoskrnl/se/token.c

index 2ca013b..b207fb9 100644 (file)
@@ -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);
        }
index dd10b6d..904ed69 100644 (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,
index c8fd044..be2be14 100644 (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;
index b16186b..9256f1c 100644 (file)
@@ -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);
index c6773eb..a983a16 100644 (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
index 41dd9fe..bfd0718 100644 (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;
+}
index 72a8fd5..ff30acc 100644 (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
index 39c8927..56a552d 100644 (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,
-                                              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;
index 097a018..5264f75 100644 (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);
index 59c620c..cca19c9 100644 (file)
@@ -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;
-
-      ret = MmCopyFromCaller(&V86Registers,
-                             ControlData,
-                             sizeof(KV86M_REGISTERS));
-      if(!NT_SUCCESS(ret)) return ret;
-
-      /* FIXME: This should use ->VdmObjects */
-      KeGetCurrentProcess()->Unused = 1;
-      Ki386RetToV86Mode(&V86Registers, &V86Registers);
-
-      /* FIXME: This should use ->VdmObjects */
-      KeGetCurrentProcess()->Unused = 0;
-
-      ret = MmCopyToCaller(ControlData,
-                           &V86Registers,
-                           sizeof(KV86M_REGISTERS));
-      if(!NT_SUCCESS(ret)) return ret;
-
-      break;
+      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;
+          
+          ProbeForWrite(ControlData,
+                        sizeof(KV86M_REGISTERS),
+                        1);
+          memcpy(&V86Registers,
+                 ControlData,
+                 sizeof(KV86M_REGISTERS));
+
+          /* FIXME: This should use ->VdmObjects */
+          KeGetCurrentProcess()->Unused = 1;
+          Ki386RetToV86Mode(&V86Registers, &V86Registers);
+
+          /* 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 */
index 6020915..35ff36f 100644 (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,
-                               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;
+           }
+         else
+           {
+               RtlCopyMemory(UnsafeConnectData,
+                             ConnectData,
+                             ConnectDataLength);
+               *UnsafeConnectDataLength = ConnectDataLength;
            }
-         MmCopyToCaller(UnsafeConnectDataLength,
-                        &ConnectDataLength,
-                        sizeof(ULONG));
+
+          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))
-    {
-      return(Status);
-    }
-  if (UnsafeWriteMap != NULL)
-    {
-      Status = MmCopyToCaller(UnsafeWriteMap,
-                             &WriteMap,
-                             sizeof(LPC_SECTION_WRITE));
-      if (!NT_SUCCESS(Status))
-       {
-         return(Status);
-       }
-    }
-  if (UnsafeReadMap != NULL)
-    {
-      Status = MmCopyToCaller(UnsafeReadMap,
-                             &ReadMap,
-                             sizeof(LPC_SECTION_READ));
+
+  if (PreviousMode != KernelMode)
+    {
+      _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 (UnsafeMaximumMessageSize != NULL)
+  else
     {
-      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;
+        }
     }
 
   /*
index 45db8da..b3c7af8 100644 (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,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))
      {
index 6fa0a07..b1b8abb 100644 (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,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
index 6c827cf..7141a09 100644 (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
-
 /*****************************************************************************/
 
        /*
index 57eead2..ee32c2b 100644 (file)
 
 /* 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))
index dd5f005..8886555 100644 (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;
index 84cee35..e0fe34b 100644 (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))
-      {
-         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)
-   {
-      MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
+          if (UnsafeResultLength != NULL)
+            {
+              *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;
-
-   Status = MmCopyFromCaller(&BaseAddress, UnsafeBaseAddress, sizeof(PVOID));
-   if (!NT_SUCCESS(Status))
-      return Status;
-   Status = MmCopyFromCaller(&NumberOfBytesToProtect, UnsafeNumberOfBytesToProtect, sizeof(ULONG));
-   if (!NT_SUCCESS(Status))
-      return Status;
+   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;
+       
+       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);
 }
 
 /*
index 799c71b..514da8f 100644 (file)
@@ -688,8 +688,6 @@ MmAllocateNonCachedMemory@4
 MmAllocatePagesForMdl@28
 MmBuildMdlForNonPagedPool@4
 MmCanFileBeTruncated@8
-;MmCopyFromCaller@12
-;MmCopyToCaller@12
 MmCreateMdl@12
 MmCreateSection@32
 MmDbgTranslatePhysicalAddress@8
index cae8cae..bdf17a8 100644 (file)
@@ -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);
+       _SEH_TRY
+         {
+           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;
      }
-   if (ReturnLength)
+   else
      {
-       NTSTATUS Status2;
-       static ULONG Null = 0;
-       Status2 = MmCopyToCaller(ReturnLength,
-                               NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
-                               sizeof(ULONG));
-       if (NT_SUCCESS(Status))
+       if (QueryInformationData[ThreadInformationClass].Size)
          {
-          Status = Status2;
-        }
+           RtlCopyMemory(ThreadInformation,
+                         &u.TBI,
+                         QueryInformationData[ThreadInformationClass].Size);
+         }
+
+       if (ReturnLength != NULL)
+         {
+           *ReturnLength = QueryInformationData[ThreadInformationClass].Size;
+         }
      }
 
    ObDereferenceObject(Thread);
index ad41dd4..8873581 100644 (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,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))