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);