added buffer checks to NtCreateThread()
Modified: trunk/reactos/ntoskrnl/ps/create.c

Modified: trunk/reactos/ntoskrnl/ps/create.c
--- trunk/reactos/ntoskrnl/ps/create.c	2005-01-28 21:17:11 UTC (rev 13357)
+++ trunk/reactos/ntoskrnl/ps/create.c	2005-01-28 22:43:13 UTC (rev 13358)
@@ -421,7 +421,7 @@
    Status = ObCreateObject(UserMode,
 			   PsThreadType,
 			   ThreadAttributes,
-			   UserMode,
+			   KernelMode,
 			   NULL,
 			   sizeof(ETHREAD),
 			   0,
@@ -443,19 +443,6 @@
     }
   Thread->ThreadsProcess = Process;
   Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId;
-  
-  Status = ObInsertObject ((PVOID)Thread,
-			   NULL,
-			   DesiredAccess,
-			   0,
-			   NULL,
-			   ThreadHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject (Thread);
-      ObDereferenceObject (Process);
-      return Status;
-    }
 
    DPRINT("Thread = %x\n",Thread);
 
@@ -488,8 +475,14 @@
    KeReleaseDispatcherDatabaseLock(oldIrql);
 
    *ThreadPtr = Thread;
-
-   return(STATUS_SUCCESS);
+   
+   Status = ObInsertObject((PVOID)Thread,
+			   NULL,
+			   DesiredAccess,
+			   0,
+			   NULL,
+			   ThreadHandle);
+   return(Status);
 }
 
 
@@ -663,25 +656,72 @@
 	       IN ACCESS_MASK DesiredAccess,
 	       IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
 	       IN HANDLE ProcessHandle,
-	       OUT PCLIENT_ID Client,
+	       OUT PCLIENT_ID ClientId,
 	       IN PCONTEXT ThreadContext,
 	       IN PINITIAL_TEB InitialTeb,
 	       IN BOOLEAN CreateSuspended)
 {
+  HANDLE hThread;
+  CONTEXT SafeContext;
+  INITIAL_TEB SafeInitialTeb;
   PEPROCESS Process;
   PETHREAD Thread;
   PTEB TebBase;
-  NTSTATUS Status;
   PKAPC LdrInitApc;
   KIRQL oldIrql;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  if(ThreadContext == NULL)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+  
+  PreviousMode = ExGetPreviousMode();
 
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForWrite(ThreadHandle,
+                    sizeof(HANDLE),
+                    sizeof(ULONG));
+      if(ClientId != NULL)
+      {
+        ProbeForWrite(ClientId,
+                      sizeof(CLIENT_ID),
+                      sizeof(ULONG));
+      }
+      ProbeForRead(ThreadContext,
+                   sizeof(CONTEXT),
+                   sizeof(ULONG));
+      SafeContext = *ThreadContext;
+      ThreadContext = &SafeContext;
+      ProbeForRead(InitialTeb,
+                   sizeof(INITIAL_TEB),
+                   sizeof(ULONG));
+      SafeInitialTeb = *InitialTeb;
+      InitialTeb = &SafeInitialTeb;
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+
   DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
 	 ThreadHandle,ThreadContext);
 
   Status = ObReferenceObjectByHandle(ProcessHandle,
                                      PROCESS_CREATE_THREAD,
                                      PsProcessType,
-                                     UserMode,
+                                     PreviousMode,
                                      (PVOID*)&Process,
                                      NULL);
   if(!NT_SUCCESS(Status))
@@ -691,7 +731,7 @@
 
   Status = PsInitializeThread(Process,
 			      &Thread,
-			      ThreadHandle,
+			      &hThread,
 			      DesiredAccess,
 			      ObjectAttributes,
 			      FALSE);
@@ -721,11 +761,6 @@
 
   Thread->StartAddress = NULL;
 
-  if (Client != NULL)
-    {
-      *Client = Thread->Cid;
-    }
-
   /*
    * Maybe send a message to the process's debugger
    */
@@ -767,8 +802,21 @@
   PsUnblockThread(Thread, NULL, 0);
   KeReleaseDispatcherDatabaseLock(oldIrql);
 
+  _SEH_TRY
+  {
+    if(ClientId != NULL)
+    {
+      *ClientId = Thread->Cid;
+    }
+    *ThreadHandle = hThread;
+  }
+  _SEH_HANDLE
+  {
+    Status = _SEH_GetExceptionCode();
+  }
+  _SEH_END;
 
-  return(STATUS_SUCCESS);
+  return Status;
 }