Fix merge r65567.
[reactos.git] / ntoskrnl / ob / obsecure.c
index 28014b4..3009c44 100644 (file)
@@ -62,17 +62,17 @@ ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
     EX_FAST_REF FastRef;
     ULONG Count;
     PSECURITY_DESCRIPTOR OldSecurityDescriptor;
-    
+
     /* Get the fast reference and capture it */
     FastRef = *(PEX_FAST_REF)SecurityDescriptor;
-    
+
     /* Don't free again later */
     *SecurityDescriptor = NULL;
-    
+
     /* Get the descriptor and reference count */
     OldSecurityDescriptor = ExGetObjectFastReference(FastRef);
     Count = ExGetCountFastReference(FastRef);
-    
+
     /* Dereference the descriptor */
     ObDereferenceSecurityDescriptor(OldSecurityDescriptor, Count + 1);
 
@@ -144,61 +144,54 @@ ObSetSecurityDescriptorInfo(IN PVOID Object,
                                              &NewDescriptor,
                                              PoolType,
                                              GenericMapping);
-        if (NT_SUCCESS(Status))
+        if (!NT_SUCCESS(Status))
         {
-            /* Now add this to the cache */
-            Status = ObLogSecurityDescriptor(NewDescriptor,
-                                             &CachedDescriptor,
-                                             MAX_FAST_REFS + 1);
-
-            /* Let go of our uncached copy */
-            ExFreePool(NewDescriptor);
-
-            /* Check for success */
-            if (NT_SUCCESS(Status))
-            {
-                /* Do the swap */
-                FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
-                OldValue = ExCompareSwapFastReference(FastRef,
-                                                      CachedDescriptor,
-                                                      OldDescriptor);
-                
-                /* Get the security descriptor */
-                SecurityDescriptor = ExGetObjectFastReference(OldValue);
-                Count = ExGetCountFastReference(OldValue);
-                
-                /* Make sure the swap worked */
-                if (SecurityDescriptor == OldDescriptor)
-                {
-                    /* Flush waiters */
-                    ObpAcquireObjectLock(ObjectHeader);
-                    ObpReleaseObjectLock(ObjectHeader);
-
-                    /* And dereference the old one */
-                    ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
-                    break;
-                }
-                else
-                {
-                    /* Someone changed it behind our back -- try again */
-                    ObDereferenceSecurityDescriptor(OldDescriptor, 1);
-                    ObDereferenceSecurityDescriptor(CachedDescriptor,
-                                                    MAX_FAST_REFS + 1);
-                }
-            }
-            else
-            {
-                /* We failed, dereference the old one */
-                ObDereferenceSecurityDescriptor(OldDescriptor, 1);
-                break;
-            }
+            /* We failed, dereference the old one */
+            if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
+            break;
         }
-        else
+
+        /* Now add this to the cache */
+        Status = ObLogSecurityDescriptor(NewDescriptor,
+                                         &CachedDescriptor,
+                                         MAX_FAST_REFS + 1);
+
+        /* Let go of our uncached copy */
+        ExFreePool(NewDescriptor);
+
+        /* Check for success */
+        if (!NT_SUCCESS(Status))
         {
             /* We failed, dereference the old one */
-            if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
+            ObDereferenceSecurityDescriptor(OldDescriptor, 1);
             break;
         }
+
+        /* Do the swap */
+        FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
+        OldValue = ExCompareSwapFastReference(FastRef,
+                                              CachedDescriptor,
+                                              OldDescriptor);
+
+        /* Make sure the swap worked */
+        if (ExGetObjectFastReference(OldValue) == OldDescriptor)
+        {
+            /* Flush waiters */
+            ObpAcquireObjectLock(ObjectHeader);
+            ObpReleaseObjectLock(ObjectHeader);
+
+            /* And dereference the old one */
+            Count = ExGetCountFastReference(OldValue);
+            ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
+            break;
+        }
+        else
+        {
+            /* Someone changed it behind our back -- try again */
+            ObDereferenceSecurityDescriptor(OldDescriptor, 1);
+            ObDereferenceSecurityDescriptor(CachedDescriptor,
+                                            MAX_FAST_REFS + 1);
+        }
     }
 
     /* Return status */
@@ -217,7 +210,7 @@ ObCheckCreateObjectAccess(IN PVOID Object,
 {
     POBJECT_HEADER ObjectHeader;
     POBJECT_TYPE ObjectType;
-    PSECURITY_DESCRIPTOR SecurityDescriptor;
+    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
     BOOLEAN SdAllocated;
     BOOLEAN Result = TRUE;
     ACCESS_MASK GrantedAccess = 0;
@@ -280,7 +273,7 @@ ObpCheckTraverseAccess(IN PVOID Object,
 {
     POBJECT_HEADER ObjectHeader;
     POBJECT_TYPE ObjectType;
-    PSECURITY_DESCRIPTOR SecurityDescriptor;
+    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
     BOOLEAN SdAllocated;
     BOOLEAN Result;
     ACCESS_MASK GrantedAccess = 0;
@@ -301,6 +294,20 @@ ObpCheckTraverseAccess(IN PVOID Object,
         return FALSE;
     }
 
+    /* First try to perform a fast traverse check
+     * If it fails, then the entire access check will
+     * have to be done.
+     */
+    Result = SeFastTraverseCheck(SecurityDescriptor,
+                                 AccessState,
+                                 FILE_WRITE_DATA,
+                                 AccessMode);
+    if (Result)
+    {
+        ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
+        return TRUE;
+    }
+
     /* Lock the security context */
     SeLockSubjectContext(&AccessState->SubjectSecurityContext);
 
@@ -338,7 +345,7 @@ ObpCheckObjectReference(IN PVOID Object,
 {
     POBJECT_HEADER ObjectHeader;
     POBJECT_TYPE ObjectType;
-    PSECURITY_DESCRIPTOR SecurityDescriptor;
+    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
     BOOLEAN SdAllocated;
     BOOLEAN Result;
     ACCESS_MASK GrantedAccess = 0;
@@ -996,7 +1003,7 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
     PAGED_CODE();
 
     /* Check if we're dealing with a kernel handle */
-    if (ObIsKernelHandle(Handle, ExGetPreviousMode()))
+    if (ObpIsKernelHandle(Handle, ExGetPreviousMode()))
     {
         /* Use the kernel table and convert the handle */
         HandleTable = ObpKernelHandleTable;