https://git.reactos.org/?p=reactos.git;a=commitdiff;h=04ff7481b1da008b4e493…
commit 04ff7481b1da008b4e49354dda548ff8aa4853de
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sun Oct 14 23:16:36 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Tue Jan 1 16:20:13 2019 +0100
[LDR] Introduce a private heap for the loader.
This ensures we can still do stuff when the process heap is corrupted.
---
dll/ntdll/include/ntdllp.h | 1 +
dll/ntdll/ldr/ldrinit.c | 20 ++++++++++++++------
dll/ntdll/ldr/ldrutils.c | 36 ++++++++++++++++++------------------
3 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/dll/ntdll/include/ntdllp.h b/dll/ntdll/include/ntdllp.h
index 934a4b2205..11f1e826f3 100644
--- a/dll/ntdll/include/ntdllp.h
+++ b/dll/ntdll/include/ntdllp.h
@@ -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;
diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c
index e40db1717a..bc72c952cd 100644
--- a/dll/ntdll/ldr/ldrinit.c
+++ b/dll/ntdll/ldr/ldrinit.c
@@ -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)
diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c
index aa18d0384f..5b6e26abd9 100644
--- a/dll/ntdll/ldr/ldrutils.c
+++ b/dll/ntdll/ldr/ldrutils.c
@@ -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