[NTOS:SE] Do not use a global lock for tokens (#3445)

In Windows Server 2003 the lock is initialised on a per-token basis, that is, the lock resource is created in SepDuplicateToken() and SepCreateToken() functions. This ensures that the lock initialisation is done locally for the specific token thus avoiding the need of a global lock.
This commit is contained in:
George Bișoc 2021-02-05 10:10:19 +01:00 committed by GitHub
parent b705df731e
commit dd4c113594
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 7 deletions

View file

@ -181,6 +181,7 @@
#define TAG_SE_HANDLES_TAB 'aHeS'
#define TAG_SE_DIR_BUFFER 'bDeS'
#define TAG_SE_PROXY_DATA 'dPoT'
#define TAG_SE_TOKEN_LOCK 'lTeS'
/* LPC Tags */
#define TAG_LPC_MESSAGE 'McpL'

View file

@ -27,7 +27,6 @@ typedef struct _TOKEN_AUDIT_POLICY_INFORMATION
/* GLOBALS ********************************************************************/
POBJECT_TYPE SeTokenObjectType = NULL;
ERESOURCE SepTokenLock; // FIXME: Global lock!
TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}};
LUID SeSystemAuthenticationId = SYSTEM_LUID;
@ -83,6 +82,59 @@ static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = {
/* FUNCTIONS *****************************************************************/
/**
* @brief
* Creates a lock for the token.
*
* @param[in,out] Token
* A token which lock has to be created.
*
* @return
* STATUS_SUCCESS if the pool allocation and resource initialisation have
* completed successfully, otherwise STATUS_INSUFFICIENT_RESOURCES on a
* pool allocation failure.
*/
static
NTSTATUS
SepCreateTokenLock(
_Inout_ PTOKEN Token)
{
PAGED_CODE();
Token->TokenLock = ExAllocatePoolWithTag(NonPagedPool,
sizeof(ERESOURCE),
TAG_SE_TOKEN_LOCK);
if (Token->TokenLock == NULL)
{
DPRINT1("SepCreateTokenLock(): Failed to allocate memory!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
ExInitializeResourceLite(Token->TokenLock);
return STATUS_SUCCESS;
}
/**
* @brief
* Deletes a lock of a token.
*
* @param[in,out] Token
* A token which contains the lock.
*
* @return
* Nothing.
*/
static
VOID
SepDeleteTokenLock(
_Inout_ PTOKEN Token)
{
PAGED_CODE();
ExDeleteResourceLite(Token->TokenLock);
ExFreePoolWithTag(Token->TokenLock, TAG_SE_TOKEN_LOCK);
}
static NTSTATUS
SepCompareTokens(IN PTOKEN FirstToken,
IN PTOKEN SecondToken,
@ -477,7 +529,13 @@ SepDuplicateToken(
AccessToken->TokenType = TokenType;
AccessToken->ImpersonationLevel = Level;
AccessToken->TokenLock = &SepTokenLock; // FIXME: Global lock!
/* Initialise the lock for the access token */
Status = SepCreateTokenLock(AccessToken);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(AccessToken);
return Status;
}
/* Copy the immutable fields */
RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
@ -491,7 +549,6 @@ SepDuplicateToken(
AccessToken->ExpirationTime = Token->ExpirationTime;
AccessToken->OriginatingLogonSession = Token->OriginatingLogonSession;
/* Lock the source token and copy the mutable fields */
SepAcquireTokenLockExclusive(Token);
@ -819,6 +876,10 @@ SepDeleteToken(PVOID ObjectBody)
if ((AccessToken->TokenFlags & TOKEN_SESSION_NOT_REFERENCED) == 0)
SepRmDereferenceLogonSession(&AccessToken->AuthenticationId);
/* Delete the token lock */
if (AccessToken->TokenLock)
SepDeleteTokenLock(AccessToken);
/* Delete the dynamic information area */
if (AccessToken->DynamicPart)
ExFreePoolWithTag(AccessToken->DynamicPart, TAG_TOKEN_DYNAMIC);
@ -833,8 +894,6 @@ SepInitializeTokenImplementation(VOID)
UNICODE_STRING Name;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
ExInitializeResource(&SepTokenLock); // FIXME: Global lock!
DPRINT("Creating Token Object Type\n");
/* Initialize the Token type */
@ -976,7 +1035,10 @@ SepCreateToken(
AccessToken->TokenType = TokenType;
AccessToken->ImpersonationLevel = ImpersonationLevel;
AccessToken->TokenLock = &SepTokenLock; // FIXME: Global lock!
/* Initialise the lock for the access token */
Status = SepCreateTokenLock(AccessToken);
if (!NT_SUCCESS(Status))
goto Quit;
RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
&TokenSource->SourceIdentifier);

View file

@ -188,7 +188,7 @@ typedef struct _TOKEN
LUID AuthenticationId; /* 0x18 */
LUID ParentTokenId; /* 0x20 */
LARGE_INTEGER ExpirationTime; /* 0x28 */
struct _ERESOURCE *TokenLock; /* 0x30 */
PERESOURCE TokenLock; /* 0x30 */
SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */
LUID ModifiedId; /* 0x40 */
ULONG SessionId; /* 0x48 */