Improvements to NtAdjustPrivilegesToken part 4 (last one):
authorEric Kohl <eric.kohl@reactos.org>
Tue, 7 Sep 2010 15:08:29 +0000 (15:08 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 7 Sep 2010 15:08:29 +0000 (15:08 +0000)
- SEH-protect all code that writes to PreviousState as it cannot be captured.
- Add a missing ObDereferenceObject and SeReleaseLuidAndAttributesArray.

svn path=/trunk/; revision=48721

reactos/ntoskrnl/se/token.c

index 31018d8..d13bc1a 100644 (file)
@@ -2117,6 +2117,15 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
+            /* Dereference the token */
+            ObDereferenceObject(Token);
+
+            /* Release the captured privileges */
+            if (CapturedPrivileges != NULL)
+                SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+                                                PreviousMode,
+                                                TRUE);
+
             /* Return the exception code */
             _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
@@ -2125,7 +2134,10 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
         /* Fail, if the buffer length is smaller than the required length */
         if (BufferLength < RequiredLength)
         {
+            /* Dereference the token */
             ObDereferenceObject(Token);
+
+            /* Release the captured privileges */
             if (CapturedPrivileges != NULL)
                 SeReleaseLuidAndAttributesArray(CapturedPrivileges,
                                                 PreviousMode,
@@ -2137,69 +2149,87 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
 
     /* Change the privilege attributes */
     ChangeCount = 0;
-    for (i = 0; i < Token->PrivilegeCount; i++)
+    _SEH2_TRY
     {
-        if (DisableAllPrivileges == TRUE)
+        for (i = 0; i < Token->PrivilegeCount; i++)
         {
-            if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
+            if (DisableAllPrivileges == TRUE)
             {
-                DPRINT ("Privilege enabled\n");
-
-                /* Save the current privilege */
-                if (PreviousState != NULL)
+                if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
                 {
-                    PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
-                    PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
-                }
+                    DPRINT("Privilege enabled\n");
+
+                    /* Save the current privilege */
+                    if (PreviousState != NULL)
+                    {
+                        PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
+                        PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
+                    }
 
-                /* Disable the current privlege */
-                Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+                    /* Disable the current privlege */
+                    Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
 
-                ChangeCount++;
+                    ChangeCount++;
+                }
             }
-        }
-        else
-        {
-            for (j = 0; j < CapturedCount; j++)
+            else
             {
-                if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart &&
-                    Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart)
+                for (j = 0; j < CapturedCount; j++)
                 {
-                    DPRINT ("Found privilege\n");
-
-                    /* Check whether the attributes differ */
-                    if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
-                        (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED))
+                    if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart &&
+                        Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart)
                     {
-                        DPRINT ("Attributes differ\n");
-                        DPRINT ("Current attributes %lx  New attributes %lx\n",
-                                Token->Privileges[i].Attributes,
-                                CapturedPrivileges[j].Attributes);
+                        DPRINT("Found privilege\n");
 
-                        /* Save the current privilege */
-                        if (PreviousState != NULL)
+                        /* Check whether the attributes differ */
+                        if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
+                            (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED))
                         {
-                            PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
-                            PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
-                        }
+                            DPRINT("Attributes differ\n");
+                            DPRINT("Current attributes %lx  New attributes %lx\n",
+                                   Token->Privileges[i].Attributes,
+                                   CapturedPrivileges[j].Attributes);
 
-                        /* Update the current privlege */
-                        Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
-                        Token->Privileges[i].Attributes |=
-                        (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED);
-                        DPRINT ("New attributes %lx\n",
-                                Token->Privileges[i].Attributes);
+                            /* Save the current privilege */
+                            if (PreviousState != NULL)
+                            {
+                                PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
+                                PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
+                            }
 
-                        ChangeCount++;
+                            /* Update the current privlege */
+                            Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+                            Token->Privileges[i].Attributes |=
+                            (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED);
+                            DPRINT("New attributes %lx\n",
+                                   Token->Privileges[i].Attributes);
+
+                            ChangeCount++;
+                        }
                     }
                 }
             }
         }
+
+        /* Set the number of saved privileges */
+        if (PreviousState != NULL)
+            PreviousState->PrivilegeCount = ChangeCount;
     }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Dereference the token */
+        ObDereferenceObject(Token);
 
-    /* Set the number of saved privileges */
-    if (PreviousState != NULL)
-        PreviousState->PrivilegeCount = ChangeCount;
+        /* Release the captured privileges */
+        if (CapturedPrivileges != NULL)
+            SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+                                            PreviousMode,
+                                            TRUE);
+
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END;
 
     /* Set the status */
     Status = (ChangeCount < CapturedCount) ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;