https://git.reactos.org/?p=reactos.git;a=commitdiff;h=20c1da7963debb69a46cf9f19f3e4c5e504c7fc9

commit 20c1da7963debb69a46cf9f19f3e4c5e504c7fc9
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Thu May 10 21:37:30 2018 +0200
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Sat Jun 5 14:39:29 2021 +0200

    [RTL][KMTEST] RtlPcToFileHeader doesn't handle user mode images in kernel 
mode
---
 modules/rostests/kmtests/rtl/RtlStack.c | 64 +++++++++++++++++++++++++++++++++
 ntoskrnl/rtl/libsupp.c                  | 11 ++++--
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/modules/rostests/kmtests/rtl/RtlStack.c 
b/modules/rostests/kmtests/rtl/RtlStack.c
index 45db416e152..273be2cc283 100644
--- a/modules/rostests/kmtests/rtl/RtlStack.c
+++ b/modules/rostests/kmtests/rtl/RtlStack.c
@@ -130,7 +130,71 @@ TestStackWalk1(VOID)
     TestStackWalk2();
 }
 
+#ifdef _M_AMD64
+NTSYSAPI
+PVOID
+NTAPI
+RtlPcToFileHeader(
+    _In_  PVOID PcValue,
+    _Out_ PVOID *BaseOfImage);
+
+extern char __ImageBase;
+
+DECLSPEC_NOINLINE
+static
+VOID
+TestRtlPcToFileHeader(VOID)
+{
+    PVOID ImageBase, Result;
+    PTEB Teb;
+    PPEB Peb;
+
+    /* First test a function from this image */
+    Result = RtlPcToFileHeader(&TestRtlPcToFileHeader, &ImageBase);
+    ok_eq_pointer(Result, ImageBase);
+    ok_eq_pointer(ImageBase, &__ImageBase);
+
+#ifdef NTOS_MODE_USER
+    Teb = NtCurrentTeb();
+#else
+    Teb = KeGetCurrentThread()->Teb;
+#endif
+    ok(Teb != NULL, "Teb is NULL!\n");
+    if (Teb == NULL)
+    {
+        return;
+    }
+
+    _SEH2_TRY
+    {
+        Peb = Teb->ProcessEnvironmentBlock;
+        ok(Peb != NULL, "Peb is NULL!\n");
+        if (Peb == NULL)
+        {
+            return;
+        }
+
+        /* Test an address somewhere within the main image of the current 
process */
+        Result = RtlPcToFileHeader((PUCHAR)Peb->ImageBaseAddress + 0x1000, 
&ImageBase);
+        ok_eq_pointer(Result, ImageBase);
+#ifdef NTOS_MODE_USER
+        ok_eq_pointer(ImageBase, Peb->ImageBaseAddress);
+#else
+        ok_eq_pointer(ImageBase, NULL);
+#endif
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        ok(FALSE, "Got an exception!\n");
+    }
+    _SEH2_END
+}
+#endif // _M_AMD64
+
 START_TEST(RtlStack)
 {
     TestStackWalk1();
+#ifdef _M_AMD64
+    TestRtlPcToFileHeader();
+#endif // _M_AMD64
 }
diff --git a/ntoskrnl/rtl/libsupp.c b/ntoskrnl/rtl/libsupp.c
index c1ded68d35c..432b9185b40 100644
--- a/ntoskrnl/rtl/libsupp.c
+++ b/ntoskrnl/rtl/libsupp.c
@@ -37,17 +37,24 @@ RtlPcToFileHeader(
 {
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     BOOLEAN InSystem;
+    KIRQL OldIrql;
 
     /* Get the base for this file */
     if ((ULONG_PTR)PcValue > (ULONG_PTR)MmHighestUserAddress)
     {
+        /* Acquire the loaded module spinlock */
+        KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql);
+
         /* We are in kernel */
         *BaseOfImage = KiPcToFileHeader(PcValue, &LdrEntry, FALSE, &InSystem);
+
+        /* Release lock */
+        KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql);
     }
     else
     {
-        /* We are in user land */
-        *BaseOfImage = KiRosPcToUserFileHeader(PcValue, &LdrEntry);
+        /* User mode is not handled here! */
+        *BaseOfImage = NULL;
     }
 
     return *BaseOfImage;

Reply via email to