[ros-diffs] [ion] 22244: - Make sure callers of NtMakeTemporaryObject have DELETE privileges, otherwise they could end up illegaly killing objects (in certain situations) - Make sure callers of NtMakePermanentObject have SeCreatePermanentPrivilege. - Implement ObpDeleteNameCheck as described in Gl00my's Ob Documentation (using such documentation falls under US Reverse Engineering Law - Clean rooming). - Remove duplicated code in ObpDecrementHandleCount and ObpSetPermanentObject and have them use ObpDeleteNameCheck instead. - Fixes thanks to using this routine: * Name-check is now properly done. * The keep-alive reference is now deleted when going from permanent->temporary object. * The parent directory is now dereferenced and cleared when deleting the object. * The security procedure is now called to delete the SD, and the name buffer is freed. - Remove ObGetObjectHandleCount, it's not a public function.

ion at svn.reactos.org ion at svn.reactos.org
Tue Jun 6 06:52:09 CEST 2006


Author: ion
Date: Tue Jun  6 08:52:08 2006
New Revision: 22244

URL: http://svn.reactos.ru/svn/reactos?rev=22244&view=rev
Log:
- Make sure callers of NtMakeTemporaryObject have DELETE privileges, otherwise they could end up illegaly killing objects (in certain situations)
- Make sure callers of NtMakePermanentObject have SeCreatePermanentPrivilege.
- Implement ObpDeleteNameCheck as described in Gl00my's Ob Documentation (using such documentation falls under US Reverse Engineering Law - Clean rooming).
- Remove duplicated code in ObpDecrementHandleCount and ObpSetPermanentObject and have them use ObpDeleteNameCheck instead.
- Fixes thanks to using this routine:
  * Name-check is now properly done.
  * The keep-alive reference is now deleted when going from permanent->temporary object.
  * The parent directory is now dereferenced and cleared when deleting the object.
  * The security procedure is now called to delete the SD, and the name buffer is freed. 
- Remove ObGetObjectHandleCount, it's not a public function.


Modified:
    trunk/reactos/ntoskrnl/cm/registry.c
    trunk/reactos/ntoskrnl/include/internal/ob.h
    trunk/reactos/ntoskrnl/ob/obhandle.c

Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=22244&r1=22243&r2=22244&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Tue Jun  6 08:52:08 2006
@@ -23,6 +23,7 @@
 #endif
 
 #define ObGetObjectPointerCount(x) OBJECT_TO_OBJECT_HEADER(x)->PointerCount
+#define ObGetObjectHandleCount(x) OBJECT_TO_OBJECT_HEADER(x)->HandleCount
 
 /* GLOBALS ******************************************************************/
 

Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ob.h?rev=22244&r1=22243&r2=22244&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Tue Jun  6 08:52:08 2006
@@ -114,9 +114,11 @@
     IN PVOID Context
 );
 
-ULONG
-NTAPI
-ObGetObjectHandleCount(PVOID Object);
+VOID
+NTAPI
+ObpDeleteNameCheck(
+    IN PVOID Object
+);
 
 NTSTATUS
 NTAPI

Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=22244&r1=22243&r2=22244&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Tue Jun  6 08:52:08 2006
@@ -21,6 +21,70 @@
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
+VOID
+NTAPI
+ObpDeleteNameCheck(IN PVOID Object)
+{
+    POBJECT_HEADER ObjectHeader;
+    OBP_LOOKUP_CONTEXT Context;
+    POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+    POBJECT_TYPE ObjectType;
+
+    /* Get object structures */
+    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+    ObjectType = ObjectHeader->Type;
+
+    /*
+     * Check if the handle count is 0, if the object is named,
+     * and if the object isn't a permanent object.
+     */
+    if (!(ObjectHeader->HandleCount) &&
+         (ObjectNameInfo) &&
+         (ObjectNameInfo->Name.Length) &&
+         !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
+    {
+        /* Make sure it's still inserted */
+        Context.Directory = ObjectNameInfo->Directory;
+        Context.DirectoryLocked = TRUE;
+        Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
+                                         &ObjectNameInfo->Name,
+                                         0,
+                                         FALSE,
+                                         &Context);
+        if (Object)
+        {
+            /* First delete it from the directory */
+            ObpDeleteEntryDirectory(&Context);
+
+            /* Now check if we have a security callback */
+            if (ObjectType->TypeInfo.SecurityRequired)
+            {
+                /* Call it */
+                ObjectType->TypeInfo.SecurityProcedure(Object,
+                                                       DeleteSecurityDescriptor,
+                                                       0,
+                                                       NULL,
+                                                       NULL,
+                                                       &ObjectHeader->
+                                                       SecurityDescriptor,
+                                                       ObjectType->
+                                                       TypeInfo.PoolType,
+                                                       NULL);
+            }
+
+            /* Free the name */
+            ExFreePool(ObjectNameInfo->Name.Buffer);
+            RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
+
+            /* Clear the current directory and de-reference it */
+            ObDereferenceObject(ObjectNameInfo->Directory);
+            ObDereferenceObject(Object);
+            ObjectNameInfo->Directory = NULL;
+        }
+    }
+}
+
 /*++
 * @name ObpSetPermanentObject
 *
@@ -43,32 +107,21 @@
                       IN BOOLEAN Permanent)
 {
     POBJECT_HEADER ObjectHeader;
-    OBP_LOOKUP_CONTEXT Context;
-
+
+    /* Get the header */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
-    ASSERT (ObjectHeader->PointerCount > 0);
     if (Permanent)
     {
+        /* Set it to permanent */
         ObjectHeader->Flags |= OB_FLAG_PERMANENT;
     }
     else
     {
+        /* Remove the flag */
         ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
-        if (ObjectHeader->HandleCount == 0 &&
-            OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory)
-        {
-            /* Make sure it's still inserted */
-            Context.Directory = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory;
-            Context.DirectoryLocked = TRUE;
-            if (ObpLookupEntryDirectory(OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory,
-                                        &OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Name,
-                                        0,
-                                        FALSE,
-                                        &Context))
-            {
-                ObpDeleteEntryDirectory(&Context);
-            }
-        }
+
+        /* Check if we should delete the object now */
+        ObpDeleteNameCheck(ObjectBody);
     }
 }
 
@@ -113,7 +166,6 @@
 {
     POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
     LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
-    OBP_LOOKUP_CONTEXT Context;
     DPRINT("Header: %x\n", ObjectHeader);
     DPRINT("NewHandleCount: %x\n", NewHandleCount);
     DPRINT("OBJECT_HEADER_TO_NAME_INFO: %x\n", OBJECT_HEADER_TO_NAME_INFO(ObjectHeader));
@@ -126,32 +178,8 @@
         ObjectHeader->Type->TypeInfo.CloseProcedure(NULL, ObjectBody, 0, NewHandleCount + 1, NewHandleCount + 1);
     }
 
-    if(NewHandleCount == 0)
-    {
-        if(OBJECT_HEADER_TO_NAME_INFO(ObjectHeader) && 
-            OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory != NULL &&
-            !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
-        {
-            /* delete the object from the namespace when the last handle got closed.
-            Only do this if it's actually been inserted into the namespace and
-            if it's not a permanent object. */
-
-            /* Make sure it's still inserted */
-            Context.Directory = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory;
-            Context.DirectoryLocked = TRUE;
-            if (ObpLookupEntryDirectory(OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Directory,
-                &OBJECT_HEADER_TO_NAME_INFO(ObjectHeader)->Name,
-                0,
-                FALSE,
-                &Context))
-            {
-                ObpDeleteEntryDirectory(&Context);
-            }
-        }
-
-        /* remove the keep-alive reference */
-        ObDereferenceObject(ObjectBody);
-    }
+    /* Check if we should delete the object */
+    ObpDeleteNameCheck(ObjectBody);
 }
 
 BOOLEAN
@@ -593,20 +621,6 @@
 }
 
 /* PUBLIC FUNCTIONS *********************************************************/
-
-ULONG
-NTAPI
-ObGetObjectHandleCount(PVOID Object)
-{
-    POBJECT_HEADER Header;
-
-    PAGED_CODE();
-
-    ASSERT(Object);
-    Header = OBJECT_TO_OBJECT_HEADER(Object);
-
-    return Header->HandleCount;
-}
 
 NTSTATUS
 NTAPI
@@ -1162,18 +1176,18 @@
     NTSTATUS Status;
     PAGED_CODE();
 
+    /* Reference the object for DELETE access */
     Status = ObReferenceObjectByHandle(ObjectHandle,
-                                       0,
+                                       DELETE,
                                        NULL,
                                        KeGetPreviousMode(),
                                        &ObjectBody,
                                        NULL);
     if (Status != STATUS_SUCCESS) return Status;
 
-    ObpSetPermanentObject (ObjectBody, FALSE);
-
+    /* Set it as temporary and dereference it */
+    ObpSetPermanentObject(ObjectBody, FALSE);
     ObDereferenceObject(ObjectBody);
-
     return STATUS_SUCCESS;
 }
 
@@ -1197,20 +1211,26 @@
 {
     PVOID ObjectBody;
     NTSTATUS Status;
-    PAGED_CODE();
-
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PAGED_CODE();
+
+    /* Make sure that the caller has SeCreatePermanentPrivilege */
+    Status = SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
+                                    PreviousMode);
+    if (!NT_SUCCESS(Status)) return STATUS_PRIVILEGE_NOT_HELD;
+
+    /* Reference the object */
     Status = ObReferenceObjectByHandle(ObjectHandle,
                                        0,
                                        NULL,
-                                       KeGetPreviousMode(),
+                                       PreviousMode,
                                        &ObjectBody,
                                        NULL);
     if (Status != STATUS_SUCCESS) return Status;
 
-    ObpSetPermanentObject (ObjectBody, TRUE);
-
+    /* Set it as permanent and dereference it */
+    ObpSetPermanentObject(ObjectBody, TRUE);
     ObDereferenceObject(ObjectBody);
-
     return STATUS_SUCCESS;
 }
 /* EOF */




More information about the Ros-diffs mailing list