https://git.reactos.org/?p=reactos.git;a=commitdiff;h=632fa1cfbe32dbcc1f97dc...
commit 632fa1cfbe32dbcc1f97dc96c9d6374cacf94ac7 Author: George Bișoc george.bisoc@reactos.org AuthorDate: Sun Jul 25 11:37:02 2021 +0200 Commit: George Bișoc george.bisoc@reactos.org CommitDate: Sat Jul 31 17:23:05 2021 +0200
[NTOS:SE] Handle the reference logon session of the token
When creating or duplicating an access token object, make sure that the logon session is getting referenced by the token must be inserted onto the logon reference member (a.k.a LogonSession) for proper logon session referencing tracking.
Also when a token object is about to be destroyed or that we are taking away a reference session from it, we must ensure that the referenced logon session data gets removed from the token in question. CORE-17700 --- ntoskrnl/se/token.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-)
diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c index a7b004ae034..46dbb725a89 100644 --- a/ntoskrnl/se/token.c +++ b/ntoskrnl/se/token.c @@ -865,6 +865,15 @@ SepDuplicateToken( goto Quit; }
+ /* Insert the referenced logon session into the token */ + Status = SepRmInsertLogonSessionIntoToken(AccessToken); + if (!NT_SUCCESS(Status)) + { + /* Failed to insert the logon session into the token, bail out */ + DPRINT1("SepRmInsertLogonSessionIntoToken() failed (Status 0x%lx)\n", Status); + goto Quit; + } + /* Assign the data that reside in the TOKEN's variable information area */ AccessToken->VariableLength = VariableLength; EndMem = (PVOID)&AccessToken->VariablePart; @@ -1164,10 +1173,23 @@ VOID NTAPI SepDeleteToken(PVOID ObjectBody) { + NTSTATUS Status; PTOKEN AccessToken = (PTOKEN)ObjectBody;
DPRINT("SepDeleteToken()\n");
+ /* Remove the referenced logon session from token */ + if (AccessToken->LogonSession) + { + Status = SepRmRemoveLogonSessionFromToken(AccessToken); + if (!NT_SUCCESS(Status)) + { + /* Something seriously went wrong */ + DPRINT1("SepDeleteToken(): Failed to remove the logon session from token (Status: 0x%lx)\n", Status); + return; + } + } + /* Dereference the logon session */ if ((AccessToken->TokenFlags & TOKEN_SESSION_NOT_REFERENCED) == 0) SepRmDereferenceLogonSession(&AccessToken->AuthenticationId); @@ -1359,6 +1381,15 @@ SepCreateToken( goto Quit; }
+ /* Insert the referenced logon session into the token */ + Status = SepRmInsertLogonSessionIntoToken(AccessToken); + if (!NT_SUCCESS(Status)) + { + /* Failed to insert the logon session into the token, bail out */ + DPRINT1("SepRmInsertLogonSessionIntoToken() failed (Status 0x%lx)\n", Status); + goto Quit; + } + /* Assign the data that reside in the TOKEN's variable information area */ AccessToken->VariableLength = VariableLength; EndMem = (PVOID)&AccessToken->VariablePart; @@ -3299,14 +3330,20 @@ NtSetInformationToken( if (OldTokenFlags == Token->TokenFlags) SessionReference = ULONG_MAX;
+ /* + * Otherwise if the flag was never set but just for this first time then + * remove the referenced logon session data from the token and dereference + * the logon session when needed. + */ + if (SessionReference == 0) + { + SepRmRemoveLogonSessionFromToken(Token); + SepRmDereferenceLogonSession(&Token->AuthenticationId); + } + /* Unlock the token */ SepReleaseTokenLock(Token); } - - /* Dereference the logon session if needed */ - if (SessionReference == 0) - SepRmDereferenceLogonSession(&Token->AuthenticationId); - break; }