https://git.reactos.org/?p=reactos.git;a=commitdiff;h=89c5191d3f1f74f42b31d…
commit 89c5191d3f1f74f42b31d833226dfbd09585ea88
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Sep 26 01:33:02 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Sep 28 00:45:03 2018 +0200
[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.
---
ntoskrnl/ps/security.c | 34 ++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/ntoskrnl/ps/security.c b/ntoskrnl/ps/security.c
index f696d0f3e5..e245dde563 100644
--- a/ntoskrnl/ps/security.c
+++ b/ntoskrnl/ps/security.c
@@ -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;
}