Author: ekohl Date: Tue Sep 7 15:08:29 2010 New Revision: 48721
URL: http://svn.reactos.org/svn/reactos?rev=48721&view=rev Log: Improvements to NtAdjustPrivilegesToken part 4 (last one): - SEH-protect all code that writes to PreviousState as it cannot be captured. - Add a missing ObDereferenceObject and SeReleaseLuidAndAttributesArray.
Modified: trunk/reactos/ntoskrnl/se/token.c
Modified: trunk/reactos/ntoskrnl/se/token.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/token.c?rev=487... ============================================================================== --- trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] Tue Sep 7 15:08:29 2010 @@ -2117,89 +2117,119 @@ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - - /* 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, TRUE);
+ /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* 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, + TRUE); + return STATUS_BUFFER_TOO_SMALL; } }
/* Change the privilege attributes */ ChangeCount = 0; - for (i = 0; i < Token->PrivilegeCount; i++) - { - if (DisableAllPrivileges == TRUE) - { - if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) - { - 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; - - ChangeCount++; - } - } - else - { - for (j = 0; j < CapturedCount; j++) - { - if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart && - Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart) - { - DPRINT ("Found privilege\n"); - - /* Check whether the attributes differ */ - if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) != - (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED)) - { - DPRINT ("Attributes differ\n"); - DPRINT ("Current attributes %lx New attributes %lx\n", - Token->Privileges[i].Attributes, - CapturedPrivileges[j].Attributes); - - /* Save the current privilege */ - if (PreviousState != NULL) + _SEH2_TRY + { + for (i = 0; i < Token->PrivilegeCount; i++) + { + if (DisableAllPrivileges == TRUE) + { + if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) + { + 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; + + ChangeCount++; + } + } + else + { + for (j = 0; j < CapturedCount; j++) + { + if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart && + Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart) + { + DPRINT("Found privilege\n"); + + /* 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); + + /* Save the current privilege */ + if (PreviousState != NULL) + { + PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid; + PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].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); + + 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; + } + } + } + } + + /* Set the number of saved privileges */ + if (PreviousState != NULL) + PreviousState->PrivilegeCount = ChangeCount; + } + _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()); + } + _SEH2_END;
/* Set the status */ Status = (ChangeCount < CapturedCount) ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;