[NTOS:PS] In PspSetPrimaryToken(), check also for sibling token to determine whether it is required to have the SeAssignPrimaryTokenPrivilege.

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.
This commit is contained in:
Hermès Bélusca-Maïto 2018-09-26 01:33:02 +02:00
parent 7f9282927b
commit 89c5191d3f
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View 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;
}