From dd4c113594740a4280ed2ba78705204aee5cd337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?George=20Bi=C8=99oc?= Date: Fri, 5 Feb 2021 10:10:19 +0100 Subject: [PATCH] [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. --- ntoskrnl/include/internal/tag.h | 1 + ntoskrnl/se/token.c | 74 ++++++++++++++++++++++++++++++--- sdk/include/ndk/setypes.h | 2 +- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/ntoskrnl/include/internal/tag.h b/ntoskrnl/include/internal/tag.h index 3e838c81abe..804a1a93dea 100644 --- a/ntoskrnl/include/internal/tag.h +++ b/ntoskrnl/include/internal/tag.h @@ -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' diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c index d7158d7de01..1f12e0109d2 100644 --- a/ntoskrnl/se/token.c +++ b/ntoskrnl/se/token.c @@ -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); diff --git a/sdk/include/ndk/setypes.h b/sdk/include/ndk/setypes.h index 55e0d8fdab6..7071ce8ab11 100644 --- a/sdk/include/ndk/setypes.h +++ b/sdk/include/ndk/setypes.h @@ -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 */