secure access to buffers in NtAllocateLocallyUniqueId

svn path=/trunk/; revision=13552
This commit is contained in:
Thomas Bluemel 2005-02-14 00:28:12 +00:00
parent 9a76ee5861
commit caea1ad51f
3 changed files with 64 additions and 17 deletions

View file

@ -120,6 +120,9 @@ ExfpInterlockedExchange64(LONGLONG volatile * Destination,
NTSTATUS NTSTATUS
ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation); ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation);
NTSTATUS
ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);;
#define InterlockedDecrementUL(Addend) \ #define InterlockedDecrementUL(Addend) \
(ULONG)InterlockedDecrement((PLONG)(Addend)) (ULONG)InterlockedDecrement((PLONG)(Addend))

View file

@ -15,7 +15,6 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
static KSPIN_LOCK LuidLock;
static LARGE_INTEGER LuidIncrement; static LARGE_INTEGER LuidIncrement;
static LARGE_INTEGER LuidValue; static LARGE_INTEGER LuidValue;
@ -26,34 +25,79 @@ SepInitLuid(VOID)
{ {
LUID DummyLuidValue = SYSTEM_LUID; LUID DummyLuidValue = SYSTEM_LUID;
KeInitializeSpinLock(&LuidLock);
LuidValue.u.HighPart = DummyLuidValue.HighPart; LuidValue.u.HighPart = DummyLuidValue.HighPart;
LuidValue.u.LowPart = DummyLuidValue.LowPart; LuidValue.u.LowPart = DummyLuidValue.LowPart;
LuidIncrement.QuadPart = 1; 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 * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
{ {
LARGE_INTEGER ReturnedLuid; LUID NewLuid;
KIRQL Irql; 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, Status = ExpAllocateLocallyUniqueId(&NewLuid);
&Irql);
ReturnedLuid = LuidValue;
LuidValue = RtlLargeIntegerAdd(LuidValue,
LuidIncrement);
KeReleaseSpinLock(&LuidLock,
Irql);
LocallyUniqueId->LowPart = ReturnedLuid.u.LowPart; _SEH_TRY
LocallyUniqueId->HighPart = ReturnedLuid.u.HighPart; {
*LocallyUniqueId = NewLuid;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
return(STATUS_SUCCESS); return Status;
} }

View file

@ -1415,21 +1415,21 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
return(Status); return(Status);
} }
Status = NtAllocateLocallyUniqueId(&AccessToken->TokenId); Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return(Status); return(Status);
} }
Status = NtAllocateLocallyUniqueId(&AccessToken->ModifiedId); Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return(Status); return(Status);
} }
Status = NtAllocateLocallyUniqueId(&AccessToken->AuthenticationId); Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);