securely access buffers in NtImpersonateThread()
Modified: trunk/reactos/ntoskrnl/ps/create.c

Modified: trunk/reactos/ntoskrnl/ps/create.c
--- trunk/reactos/ntoskrnl/ps/create.c	2005-01-28 19:28:24 UTC (rev 13354)
+++ trunk/reactos/ntoskrnl/ps/create.c	2005-01-28 20:48:43 UTC (rev 13355)
@@ -177,56 +177,73 @@
 		    IN HANDLE ThreadToImpersonateHandle,
 		    IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
 {
+  SECURITY_QUALITY_OF_SERVICE SafeServiceQoS;
   SECURITY_CLIENT_CONTEXT ClientContext;
   PETHREAD Thread;
   PETHREAD ThreadToImpersonate;
-  NTSTATUS Status;
-
-  Status = ObReferenceObjectByHandle (ThreadHandle,
-				      0,
-				      PsThreadType,
-				      UserMode,
-				      (PVOID*)&Thread,
-				      NULL);
-  if (!NT_SUCCESS (Status))
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
     {
-      return Status;
+      ProbeForRead(SecurityQualityOfService,
+                   sizeof(SECURITY_QUALITY_OF_SERVICE),
+                   sizeof(ULONG));
+      SafeServiceQoS = *SecurityQualityOfService;
+      SecurityQualityOfService = &SafeServiceQoS;
     }
-
-  Status = ObReferenceObjectByHandle (ThreadToImpersonateHandle,
-				      0,
-				      PsThreadType,
-				      UserMode,
-				      (PVOID*)&ThreadToImpersonate,
-				      NULL);
-  if (!NT_SUCCESS(Status))
+    _SEH_HANDLE
     {
-      ObDereferenceObject (Thread);
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
       return Status;
     }
+  }
 
-  Status = SeCreateClientSecurity (ThreadToImpersonate,
-				   SecurityQualityOfService,
-				   0,
-				   &ClientContext);
-  if (!NT_SUCCESS(Status))
+  Status = ObReferenceObjectByHandle(ThreadHandle,
+				     THREAD_IMPERSONATE,
+				     PsThreadType,
+				     PreviousMode,
+				     (PVOID*)&Thread,
+				     NULL);
+  if(NT_SUCCESS(Status))
+  {
+    Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
+				       THREAD_DIRECT_IMPERSONATION,
+				       PsThreadType,
+				       PreviousMode,
+				       (PVOID*)&ThreadToImpersonate,
+				       NULL);
+    if(NT_SUCCESS(Status))
     {
-      ObDereferenceObject (ThreadToImpersonate);
-      ObDereferenceObject (Thread);
-      return Status;
-     }
+      Status = SeCreateClientSecurity(ThreadToImpersonate,
+				      SecurityQualityOfService,
+				      0,
+				     &ClientContext);
+      if(NT_SUCCESS(Status))
+      {
+        SeImpersonateClient(&ClientContext,
+		            Thread);
+        if(ClientContext.ClientToken != NULL)
+        {
+          ObDereferenceObject (ClientContext.ClientToken);
+        }
+      }
 
-  SeImpersonateClient (&ClientContext,
-		       Thread);
-  if (ClientContext.ClientToken != NULL)
-    {
-      ObDereferenceObject (ClientContext.ClientToken);
+      ObDereferenceObject(ThreadToImpersonate);
     }
+    ObDereferenceObject(Thread);
+  }
 
-  ObDereferenceObject (ThreadToImpersonate);
-  ObDereferenceObject (Thread);
-
-  return STATUS_SUCCESS;
+  return Status;
 }
 
 /*