From caea1ad51fd1cde6b60befaec07d0f4b74f6072f Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 14 Feb 2005 00:28:12 +0000 Subject: [PATCH] secure access to buffers in NtAllocateLocallyUniqueId svn path=/trunk/; revision=13552 --- reactos/ntoskrnl/include/internal/ex.h | 3 ++ reactos/ntoskrnl/se/luid.c | 72 +++++++++++++++++++++----- reactos/ntoskrnl/se/token.c | 6 +-- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 44e5a5aeeac..2f7841c0d2c 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -120,6 +120,9 @@ ExfpInterlockedExchange64(LONGLONG volatile * Destination, NTSTATUS ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation); +NTSTATUS +ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);; + #define InterlockedDecrementUL(Addend) \ (ULONG)InterlockedDecrement((PLONG)(Addend)) diff --git a/reactos/ntoskrnl/se/luid.c b/reactos/ntoskrnl/se/luid.c index 1ea9e71c3fc..702bfcdd201 100644 --- a/reactos/ntoskrnl/se/luid.c +++ b/reactos/ntoskrnl/se/luid.c @@ -15,7 +15,6 @@ /* GLOBALS *******************************************************************/ -static KSPIN_LOCK LuidLock; static LARGE_INTEGER LuidIncrement; static LARGE_INTEGER LuidValue; @@ -26,34 +25,79 @@ SepInitLuid(VOID) { LUID DummyLuidValue = SYSTEM_LUID; - KeInitializeSpinLock(&LuidLock); LuidValue.u.HighPart = DummyLuidValue.HighPart; LuidValue.u.LowPart = DummyLuidValue.LowPart; LuidIncrement.QuadPart = 1; } +NTSTATUS +ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) +{ + LARGE_INTEGER NewLuid, PrevLuid; + + /* atomically increment the luid */ + do + { + PrevLuid = (volatile LARGE_INTEGER)LuidValue; + NewLuid = RtlLargeIntegerAdd(PrevLuid, + LuidIncrement); + } while(ExfInterlockedCompareExchange64(&LuidValue.QuadPart, + &NewLuid.QuadPart, + &PrevLuid.QuadPart) != PrevLuid.QuadPart); + + LocallyUniqueId->LowPart = NewLuid.u.LowPart; + LocallyUniqueId->HighPart = NewLuid.u.HighPart; + + return STATUS_SUCCESS; +} + + /* * @implemented */ NTSTATUS STDCALL NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) { - LARGE_INTEGER ReturnedLuid; - KIRQL Irql; + LUID NewLuid; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(LocallyUniqueId, + sizeof(LUID), + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } - KeAcquireSpinLock(&LuidLock, - &Irql); - ReturnedLuid = LuidValue; - LuidValue = RtlLargeIntegerAdd(LuidValue, - LuidIncrement); - KeReleaseSpinLock(&LuidLock, - Irql); + Status = ExpAllocateLocallyUniqueId(&NewLuid); - LocallyUniqueId->LowPart = ReturnedLuid.u.LowPart; - LocallyUniqueId->HighPart = ReturnedLuid.u.HighPart; + _SEH_TRY + { + *LocallyUniqueId = NewLuid; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - return(STATUS_SUCCESS); + return Status; } diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 62d6f9c01ef..7fbe6f72077 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1415,21 +1415,21 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process) return(Status); } - Status = NtAllocateLocallyUniqueId(&AccessToken->TokenId); + Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); return(Status); } - Status = NtAllocateLocallyUniqueId(&AccessToken->ModifiedId); + Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId); if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); return(Status); } - Status = NtAllocateLocallyUniqueId(&AccessToken->AuthenticationId); + Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId); if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken);