[LDR] Introduce a private heap for the loader. 1204/head
authorMark Jansen <mark.jansen@reactos.org>
Sun, 14 Oct 2018 21:16:36 +0000 (23:16 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Tue, 1 Jan 2019 15:20:13 +0000 (16:20 +0100)
This ensures we can still do stuff when the process heap is corrupted.

dll/ntdll/include/ntdllp.h
dll/ntdll/ldr/ldrinit.c
dll/ntdll/ldr/ldrutils.c

index 934a4b2..11f1e82 100644 (file)
@@ -32,6 +32,7 @@ typedef struct _LDRP_TLS_DATA
 /* Global data */
 extern RTL_CRITICAL_SECTION LdrpLoaderLock;
 extern BOOLEAN LdrpInLdrInit;
+extern PVOID LdrpHeap;
 extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
 extern BOOLEAN ShowSnaps;
 extern UNICODE_STRING LdrpDefaultPath;
index e40db17..bc72c95 100644 (file)
@@ -55,6 +55,7 @@ ULONG LdrpNumberOfProcessors;
 PVOID NtDllBase;
 extern LARGE_INTEGER RtlpTimeout;
 BOOLEAN RtlpTimeoutDisable;
+PVOID LdrpHeap;
 LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
 LIST_ENTRY LdrpDllNotificationList;
 HANDLE LdrpKnownDllObjectDirectory;
@@ -663,7 +664,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
         if (Count > 16)
         {
             /* Allocate space for all the entries */
-            LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+            LdrRootEntry = RtlAllocateHeap(LdrpHeap,
                                            0,
                                            Count * sizeof(*LdrRootEntry));
             if (!LdrRootEntry) return STATUS_NO_MEMORY;
@@ -921,7 +922,7 @@ Quickie:
     if (LdrRootEntry != LocalArray)
     {
         /* Free the array */
-        RtlFreeHeap(RtlGetProcessHeap(), 0, LdrRootEntry);
+        RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
     }
 
     /* Return to caller */
@@ -1752,9 +1753,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
                                               &ConfigSize);
 
     /* Setup the Heap Parameters */
-    RtlZeroMemory(&HeapParameters, sizeof(RTL_HEAP_PARAMETERS));
+    RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
     HeapFlags = HEAP_GROWABLE;
-    HeapParameters.Length = sizeof(RTL_HEAP_PARAMETERS);
+    HeapParameters.Length = sizeof(HeapParameters);
 
     /* Check if we have Configuration Data */
     if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY)))
@@ -1875,8 +1876,15 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
     if (!NT_SUCCESS(Status)) return Status;
 
-    // FIXME: Loader private heap is missing
-    //DPRINT1("Loader private heap is missing\n");
+    RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
+    HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
+    HeapParameters.Length = sizeof(HeapParameters);
+    LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
+    if (!LdrpHeap)
+    {
+        DPRINT1("Failed to create loader private heap\n");
+        return STATUS_NO_MEMORY;
+    }
 
     /* Check for Debug Heap */
     if (OptionsKey)
index aa18d03..5b6e26a 100644 (file)
@@ -50,7 +50,7 @@ LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut,
     }
 
     /* Allocate the string*/
-    StringOut->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+    StringOut->Buffer = RtlAllocateHeap(LdrpHeap,
                                         0,
                                         StringOut->Length + sizeof(WCHAR));
     if (!StringOut->Buffer)
@@ -88,7 +88,7 @@ LdrpFreeUnicodeString(IN PUNICODE_STRING StringIn)
     /* If Buffer is not NULL - free it */
     if (StringIn->Buffer)
     {
-        RtlFreeHeap(RtlGetProcessHeap(), 0, StringIn->Buffer);
+        RtlFreeHeap(LdrpHeap, 0, StringIn->Buffer);
     }
 
     /* Zero it out */
@@ -703,7 +703,7 @@ LdrpResolveDllName(PWSTR DllPath,
     ULONG BufSize = 500;
 
     /* Allocate space for full DLL name */
-    FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL));
+    FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BufSize + sizeof(UNICODE_NULL));
     if (!FullDllName->Buffer) return FALSE;
 
     Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
@@ -721,7 +721,7 @@ LdrpResolveDllName(PWSTR DllPath,
             DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
         }
 
-        RtlFreeUnicodeString(FullDllName);
+        LdrpFreeUnicodeString(FullDllName);
         return FALSE;
     }
 
@@ -730,16 +730,16 @@ LdrpResolveDllName(PWSTR DllPath,
     FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
 
     /* Allocate a new buffer */
-    NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
+    NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
     if (!NameBuffer)
     {
-        RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+        RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
         return FALSE;
     }
 
     /* Copy over the contents from the previous one and free it */
     RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
-    RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+    RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
     FullDllName->Buffer = NameBuffer;
 
     /* Find last backslash */
@@ -766,11 +766,11 @@ LdrpResolveDllName(PWSTR DllPath,
     /* Construct base DLL name */
     BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
     BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
-    BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BaseDllName->MaximumLength);
+    BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
 
     if (!BaseDllName->Buffer)
     {
-        RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
+        RtlFreeHeap(LdrpHeap, 0, NameBuffer);
         return FALSE;
     }
 
@@ -867,7 +867,7 @@ LdrpCheckForKnownDll(PWSTR DllName,
         /* Set up BaseDllName */
         BaseDllName->Length = DllNameUnic.Length;
         BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
-        BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+        BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
                                               0,
                                               DllNameUnic.MaximumLength);
         if (!BaseDllName->Buffer)
@@ -882,7 +882,7 @@ LdrpCheckForKnownDll(PWSTR DllName,
         /* Set up FullDllName */
         FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
         FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
-        FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
+        FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
         if (!FullDllName->Buffer)
         {
             Status = STATUS_NO_MEMORY;
@@ -932,8 +932,8 @@ Failure:
     if (Section) NtClose(Section);
 
     /* Free string resources */
-    if (BaseDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
-    if (FullDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+    if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
+    if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
 
     /* Return status */
     return Status;
@@ -1137,8 +1137,8 @@ SkipCheck:
             if (!NT_SUCCESS(Status))
             {
                 /* Free the name strings and return */
-                RtlFreeUnicodeString(&FullDllName);
-                RtlFreeUnicodeString(&BaseDllName);
+                LdrpFreeUnicodeString(&FullDllName);
+                LdrpFreeUnicodeString(&BaseDllName);
                 return Status;
             }
         }
@@ -1286,7 +1286,7 @@ SkipCheck:
             RemoveEntryList(&LdrEntry->HashLinks);
 
             /* Remove the LDR Entry */
-            RtlFreeHeap(RtlGetProcessHeap(), 0, LdrEntry );
+            RtlFreeHeap(LdrpHeap, 0, LdrEntry );
 
             /* Unmap and close section */
             NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
@@ -1553,7 +1553,7 @@ LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
     if (NtHeader)
     {
         /* Allocate an entry */
-        LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+        LdrEntry = RtlAllocateHeap(LdrpHeap,
                                    HEAP_ZERO_MEMORY,
                                    sizeof(LDR_DATA_TABLE_ENTRY));
 
@@ -1608,7 +1608,7 @@ LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry)
     if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
 
     /* Finally free the entry's memory */
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Entry);
+    RtlFreeHeap(LdrpHeap, 0, Entry);
 }
 
 BOOLEAN