- Fix a large amount of bugs in ObpAllocateObjectAttributes & Name
authorAlex Ionescu <aionescu@gmail.com>
Tue, 9 Aug 2005 04:43:54 +0000 (04:43 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Tue, 9 Aug 2005 04:43:54 +0000 (04:43 +0000)
svn path=/trunk/; revision=17227

reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/ob/namespc.c
reactos/ntoskrnl/ob/object.c

index 7432f50..21cb118 100644 (file)
@@ -549,13 +549,15 @@ KeWaitForMultipleObjects(ULONG Count,
         }
 
         /* Block the Thread */
-        DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
+        DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, 
+                WaitReason, KeGetCurrentThread());
         KiBlockThread(&Status,
                       Alertable,
                       WaitMode,
                       (UCHAR)WaitReason);
 
         /* Check if we were executing an APC */
+        DPRINT("Thread is back\n");
         if (Status != STATUS_KERNEL_APC) {
 
             /* Return Status */
@@ -568,7 +570,7 @@ KeWaitForMultipleObjects(ULONG Count,
     } while (TRUE);
 
     /* Release the Lock, we are done */
-    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
+    DPRINT("Returning, %x. Status: %d\n",  KeGetCurrentThread(), Status);
     KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
     return Status;
 
@@ -577,7 +579,8 @@ DontWait:
     KiAdjustQuantumThread(CurrentThread);
 
     /* Release & Return */
-    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n. We did not wait.", KeGetCurrentThread(), Status);
+    DPRINT("Returning, %x. Status: %d\n. We did not wait.", 
+            KeGetCurrentThread(), Status);
     KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
     return Status;
 }
index df73bfe..31be0d2 100644 (file)
@@ -65,30 +65,26 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
    PVOID Object = NULL;
    UNICODE_STRING RemainingPath;
    UNICODE_STRING ObjectName;
-   OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_CREATE_INFORMATION ObjectCreateInfo;
    NTSTATUS Status;
 
    PAGED_CODE();
 
-   InitializeObjectAttributes(&ObjectAttributes,
-                             ObjectPath,
-                             Attributes | OBJ_OPENIF,
-                             NULL,
-                             NULL);
-    
-   /* Capture all the info */
-   DPRINT("Capturing Create Info\n");
-   Status = ObpCaptureObjectAttributes(&ObjectAttributes,
-                                       AccessMode,
-                                       ObjectType,
-                                       &ObjectCreateInfo,
-                                       &ObjectName);
+   /* Capture the name */
+   DPRINT("Capturing Name\n");
+   Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
    if (!NT_SUCCESS(Status))
      {
-       DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+       DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
        return Status;
      }
+
+   /* 
+    * Create a fake ObjectCreateInfo structure. Note that my upcoming
+    * ObFindObject refactoring will remove the need for this hack.
+    */
+   ObjectCreateInfo.RootDirectory = NULL;
+   ObjectCreateInfo.Attributes = Attributes;
      
    Status = ObFindObject(&ObjectCreateInfo,
                          &ObjectName,
@@ -96,7 +92,6 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
                         &RemainingPath,
                         ObjectType);
 
-   ObpReleaseCapturedAttributes(&ObjectCreateInfo);
    if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
 
    if (!NT_SUCCESS(Status))
index 2467fd0..6bd1b7a 100644 (file)
@@ -17,6 +17,7 @@
 
 #define UNICODE_PATH_SEP L'\\'
 #define UNICODE_NO_PATH L"..."
+#define OB_NAME_TAG TAG('O','b','N','m')
 
 typedef struct _RETENTION_CHECK_PARAMS
 {
@@ -33,78 +34,85 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
                      IN KPROCESSOR_MODE AccessMode)
 {
     NTSTATUS Status = STATUS_SUCCESS;
+    ULONG StringLength;
+    PWCHAR StringBuffer;
     UNICODE_STRING LocalName = {}; /* <= GCC 4.0 + Optimizer */
     
-    /* First Probe the String */
-    DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName);
-    if (AccessMode != KernelMode)
+    /* Initialize the Input String */
+    RtlInitUnicodeString(CapturedName, NULL);
+
+    /* Protect everything */
+    _SEH_TRY
     {
-        DPRINT("Probing Struct\n");
-        _SEH_TRY
+        /* First Probe the String */
+        DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName);
+        if (AccessMode != KernelMode)
         {
-            /* FIXME: Explorer or win32 broken I think */
-            #if 0
             ProbeForRead(ObjectName,
                          sizeof(UNICODE_STRING),
                          sizeof(USHORT));
-            #endif
             LocalName = *ObjectName;
+
+            ProbeForRead(LocalName.Buffer,
+                         LocalName.Length,
+                         sizeof(WCHAR));
         }
-        _SEH_HANDLE
+        else
         {
-            Status = _SEH_GetExceptionCode();
+            /* No probing needed */
+            LocalName = *ObjectName;
         }
-        _SEH_END;
-        
-        if (NT_SUCCESS(Status))
+
+        /* Make sure there really is a string */
+        DPRINT("Probing OK\n");
+        if ((StringLength = LocalName.Length))
         {
-            DPRINT("Probing OK\n");
-             _SEH_TRY
+            /* Check that the size is a valid WCHAR multiple */
+            if ((StringLength & (sizeof(WCHAR) - 1)) ||
+                /* Check that the NULL-termination below will work */
+                (StringLength == (MAXUSHORT - sizeof(WCHAR) + 1)))
             {
-                #if 0
-                DPRINT("Probing buffer\n");
-                ProbeForRead(LocalName.Buffer,
-                             LocalName.Length,
-                             sizeof(USHORT));
-                #endif
+                /* PS: Please keep the checks above expanded for clarity */
+                DPRINT1("Invalid String Length\n");
+                Status = STATUS_OBJECT_NAME_INVALID;
             }
-            _SEH_HANDLE
+            else
             {
-                Status = _SEH_GetExceptionCode();
+                /* Allocate a non-paged buffer for this string */
+                DPRINT("Capturing String\n");
+                CapturedName->Length = StringLength;
+                CapturedName->MaximumLength = StringLength + sizeof(WCHAR);
+                if ((StringBuffer = ExAllocatePoolWithTag(NonPagedPool, 
+                                                          StringLength + sizeof(WCHAR),
+                                                          OB_NAME_TAG)))
+                {                                    
+                    /* Copy the string and null-terminate it */
+                    RtlMoveMemory(StringBuffer, LocalName.Buffer, StringLength);
+                    StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
+                    CapturedName->Buffer = StringBuffer;
+                    DPRINT("String Captured: %wZ\n", CapturedName);
+                }
+                else
+                {
+                    /* Fail */
+                    DPRINT1("Out of Memory!\n");
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                }
             }
-            _SEH_END;
-        }
-        
-        /* Fail if anything up to here died */
-        if (!NT_SUCCESS(Status)) 
-        {
-            DPRINT1("Probing failed\n");
-            return Status;
         }
     }
-    else
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
     {
-        LocalName = *ObjectName;
-    }
-    
-    /* Make sure there really is a string */
-    DPRINT("Probing OK\n");
-    if (LocalName.Length)
-    {
-        /* Allocate a non-paged buffer for this string */
-        DPRINT("Capturing String\n");
-        CapturedName->Length = LocalName.Length;
-        CapturedName->MaximumLength = LocalName.Length + sizeof(WCHAR);
-        CapturedName->Buffer = ExAllocatePoolWithTag(NonPagedPool, 
-                                                     CapturedName->MaximumLength,
-                                                     TAG('O','b','N','m'));
-                                                     
-        /* Copy the string and null-terminate it */
-        RtlMoveMemory(CapturedName->Buffer, LocalName.Buffer, LocalName.Length);
-        CapturedName->Buffer[LocalName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-        DPRINT("String Captured: %p, %wZ\n", CapturedName, CapturedName);
+        Status = _SEH_GetExceptionCode();
+
+        /* Remember to free the buffer in case of failure */
+        DPRINT1("Failed\n");
+        if (StringBuffer) ExFreePool(StringBuffer);
     }
+    _SEH_END;
     
+    /* Return */
+    DPRINT("Returning: %lx\n", Status);
     return Status;
 }
 
@@ -125,115 +133,102 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
     DPRINT("ObpCaptureObjectAttributes\n");
     RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
     
-    /* Check if we got Oba */
-    if (ObjectAttributes)
+    /* SEH everything here for protection */
+    _SEH_TRY
     {
-        if (AccessMode != KernelMode)
+        /* Check if we got Oba */
+        if (ObjectAttributes)
         {
-            DPRINT("Probing OBA\n");
-            _SEH_TRY
+            if (AccessMode != KernelMode)
             {
-                /* FIXME: SMSS SENDS BULLSHIT. */
-                #if 0
+                DPRINT("Probing OBA\n");
                 ProbeForRead(ObjectAttributes,
-                             sizeof(ObjectAttributes),
+                             sizeof(OBJECT_ATTRIBUTES),
                              sizeof(ULONG));
-                #endif
             }
-            _SEH_HANDLE
+        
+            /* Validate the Size and Attributes */
+            DPRINT("Validating OBA\n");
+            if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
+                (ObjectAttributes->Attributes & ~OBJ_VALID_ATTRIBUTES))
             {
-                Status = _SEH_GetExceptionCode();
+                Status = STATUS_INVALID_PARAMETER;
+                DPRINT1("Invalid Size: %lx or Attributes: %lx\n",
+                       ObjectAttributes->Length, ObjectAttributes->Attributes); 
+                goto Quickie;
             }
-            _SEH_END;
-        }
-        
-        /* Validate the Size */
-        DPRINT("Validating OBA\n");
-        if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES))
-        {
-            Status = STATUS_INVALID_PARAMETER;
-        }
-
-        /* Fail if SEH or Size Validation failed */
-        if(!NT_SUCCESS(Status))
-        {
-            DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n");
-            goto fail;
-        }
         
-        /* Set some Create Info */
-        DPRINT("Creating OBCI\n");
-        ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
-        ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
-        LocalObjectName = ObjectAttributes->ObjectName;
-        SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
-        SecurityQos = ObjectAttributes->SecurityQualityOfService;
+            /* Set some Create Info */
+            DPRINT("Creating OBCI\n");
+            ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
+            ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
+            LocalObjectName = ObjectAttributes->ObjectName;
+            SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
+            SecurityQos = ObjectAttributes->SecurityQualityOfService;
         
-        /* Validate the SD */
-        if (SecurityDescriptor)
-        {
-            DPRINT("Probing SD: %x\n", SecurityDescriptor);
-            Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
-                                                 AccessMode,
-                                                 NonPagedPool,
-                                                 TRUE,
-                                                 &ObjectCreateInfo->SecurityDescriptor);
-            if(!NT_SUCCESS(Status))
+            /* Validate the SD */
+            if (SecurityDescriptor)
             {
-                DPRINT1("Unable to capture the security descriptor!!!\n");
-                ObjectCreateInfo->SecurityDescriptor = NULL;
-                goto fail;
-            }
+                DPRINT("Probing SD: %x\n", SecurityDescriptor);
+                Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
+                                                     AccessMode,
+                                                     NonPagedPool,
+                                                     TRUE,
+                                                     &ObjectCreateInfo->SecurityDescriptor);
+                if(!NT_SUCCESS(Status))
+                {
+                    DPRINT1("Unable to capture the security descriptor!!!\n");
+                    ObjectCreateInfo->SecurityDescriptor = NULL;
+                    goto Quickie;
+                }
             
-            DPRINT("Probe done\n");
-            ObjectCreateInfo->SecurityDescriptorCharge = 0; /* FIXME */
-            ObjectCreateInfo->ProbeMode = AccessMode;
-        }
+                DPRINT("Probe done\n");
+                ObjectCreateInfo->SecurityDescriptorCharge = 2048; /* FIXME */
+                ObjectCreateInfo->ProbeMode = AccessMode;
+            }
         
-        /* Validate the QoS */
-        if (SecurityQos)
-        {
-            if (AccessMode != KernelMode)
+            /* Validate the QoS */
+            if (SecurityQos)
             {
-                DPRINT("Probing QoS\n");
-                _SEH_TRY
+                if (AccessMode != KernelMode)
                 {
+                    DPRINT("Probing QoS\n");
                     ProbeForRead(SecurityQos,
                                  sizeof(SECURITY_QUALITY_OF_SERVICE),
                                  sizeof(ULONG));
                 }
-                _SEH_HANDLE
-                {
-                    Status = _SEH_GetExceptionCode();
-                }
-                _SEH_END;
-            }
-
-            if(!NT_SUCCESS(Status))
-            {
-                DPRINT1("Unable to capture QoS!!!\n");
-                goto fail;
-            }
             
-            ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
-            ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
+                /* Save Info */
+                ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
+                ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
+            }
+        }
+        else
+        {
+            LocalObjectName = NULL;
         }
     }
-    
-    /* Clear Local Object Name */
-    DPRINT("Clearing name\n");
-    RtlZeroMemory(ObjectName, sizeof(UNICODE_STRING));
-    
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
+        Status = _SEH_GetExceptionCode();
+        DPRINT1("Failed\n");
+        goto Quickie;
+    }
+    _SEH_END;
+
     /* Now check if the Object Attributes had an Object Name */
     if (LocalObjectName)
     {
-        DPRINT("Name Buffer: %x\n", LocalObjectName->Buffer);
+        DPRINT("Name Buffer: %wZ\n", LocalObjectName);
         Status = ObpCaptureObjectName(ObjectName,
                                       LocalObjectName,
                                       AccessMode);
     }
     else
     {
+        /* Clear the string */
+        RtlInitUnicodeString(ObjectName, NULL);
+
         /* He can't have specified a Root Directory */
         if (ObjectCreateInfo->RootDirectory)
         {
@@ -242,14 +237,14 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
         }
     }
     
-fail:
+Quickie:
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to capture, cleaning up\n");
         ObpReleaseCapturedAttributes(ObjectCreateInfo);
     }
     
-    DPRINT("Return to caller\n");
+    DPRINT("Return to caller %x\n", Status);
     return Status;
 }
 
@@ -795,7 +790,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
     /* Capture all the info */
     DPRINT("Capturing Create Info\n");
     Status = ObpCaptureObjectAttributes(ObjectAttributes,
-                                        AccessMode,
+                                        ObjectAttributesAccessMode,
                                         Type,
                                         ObjectCreateInfo,
                                         &ObjectName);