[NTOS:PS] In PspSetPrimaryToken(), check also for sibling token to determine whether...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 25 Sep 2018 23:33:02 +0000 (01:33 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Thu, 27 Sep 2018 22:45:03 +0000 (00:45 +0200)
In addition, it is the presence or absence of the 'Token' pointer that indicates whether or not we should use instead the provided token handle.

ntoskrnl/ps/security.c

index f696d0f..e245dde 100644 (file)
@@ -217,18 +217,18 @@ PspSetPrimaryToken(IN PEPROCESS Process,
                    IN PACCESS_TOKEN Token OPTIONAL)
 {
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-    BOOLEAN IsChild;
+    BOOLEAN IsChildOrSibling;
     PACCESS_TOKEN NewToken = Token;
     NTSTATUS Status, AccessStatus;
     BOOLEAN Result, SdAllocated;
     PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
     SECURITY_SUBJECT_CONTEXT SubjectContext;
+
     PSTRACE(PS_SECURITY_DEBUG, "Process: %p Token: %p\n", Process, Token);
 
-    /* Make sure we got a handle */
-    if (TokenHandle)
+    /* Reference the token by handle if we don't already have a token object */
+    if (!Token)
     {
-        /* Reference it */
         Status = ObReferenceObjectByHandle(TokenHandle,
                                            TOKEN_ASSIGN_PRIMARY,
                                            SeTokenObjectType,
@@ -238,24 +238,38 @@ PspSetPrimaryToken(IN PEPROCESS Process,
         if (!NT_SUCCESS(Status)) return Status;
     }
 
-    /* Check if this is a child */
-    Status = SeIsTokenChild(NewToken, &IsChild);
+    /*
+     * Check whether this token is a child or sibling of the current process token.
+     * NOTE: On Windows Vista+ both of these checks (together with extra steps)
+     * are now performed by a new SeIsTokenAssignableToProcess() helper.
+     */
+    Status = SeIsTokenChild(NewToken, &IsChildOrSibling);
     if (!NT_SUCCESS(Status))
     {
         /* Failed, dereference */
-        if (TokenHandle) ObDereferenceObject(NewToken);
+        if (!Token) ObDereferenceObject(NewToken);
         return Status;
     }
+    if (!IsChildOrSibling)
+    {
+        Status = SeIsTokenSibling(NewToken, &IsChildOrSibling);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Failed, dereference */
+            if (!Token) ObDereferenceObject(NewToken);
+            return Status;
+        }
+    }
 
     /* Check if this was an independent token */
-    if (!IsChild)
+    if (!IsChildOrSibling)
     {
         /* Make sure we have the privilege to assign a new one */
         if (!SeSinglePrivilegeCheck(SeAssignPrimaryTokenPrivilege,
                                     PreviousMode))
         {
             /* Failed, dereference */
-            if (TokenHandle) ObDereferenceObject(NewToken);
+            if (!Token) ObDereferenceObject(NewToken);
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
@@ -314,7 +328,7 @@ PspSetPrimaryToken(IN PEPROCESS Process,
     }
 
     /* Dereference the token */
-    if (TokenHandle) ObDereferenceObject(NewToken);
+    if (!Token) ObDereferenceObject(NewToken);
     return Status;
 }