secure access to buffers in NtAllocateLocallyUniqueId Modified: trunk/reactos/ntoskrnl/include/internal/ex.h Modified: trunk/reactos/ntoskrnl/se/luid.c Modified: trunk/reactos/ntoskrnl/se/token.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h --- trunk/reactos/ntoskrnl/include/internal/ex.h 2005-02-13 23:10:36 UTC (rev 13551) +++ trunk/reactos/ntoskrnl/include/internal/ex.h 2005-02-14 00:28:12 UTC (rev 13552) @@ -120,6 +120,9 @@
NTSTATUS ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation);
+NTSTATUS +ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);; + #define InterlockedDecrementUL(Addend) \ (ULONG)InterlockedDecrement((PLONG)(Addend))
_____
Modified: trunk/reactos/ntoskrnl/se/luid.c --- trunk/reactos/ntoskrnl/se/luid.c 2005-02-13 23:10:36 UTC (rev 13551) +++ trunk/reactos/ntoskrnl/se/luid.c 2005-02-14 00:28:12 UTC (rev 13552) @@ -15,7 +15,6 @@
/* GLOBALS *******************************************************************/
-static KSPIN_LOCK LuidLock; static LARGE_INTEGER LuidIncrement; static LARGE_INTEGER LuidValue;
@@ -26,34 +25,79 @@ { 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; }
_____
Modified: trunk/reactos/ntoskrnl/se/token.c --- trunk/reactos/ntoskrnl/se/token.c 2005-02-13 23:10:36 UTC (rev 13551) +++ trunk/reactos/ntoskrnl/se/token.c 2005-02-14 00:28:12 UTC (rev 13552) @@ -1415,21 +1415,21 @@
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);