[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
This commit is contained in:
George Bișoc 2021-07-25 11:37:02 +02:00
parent 5e51f8dad2
commit 632fa1cfbe
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6

View file

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