https://git.reactos.org/?p=reactos.git;a=commitdiff;h=20c1da7963debb69a46cf…
commit 20c1da7963debb69a46cf9f19f3e4c5e504c7fc9
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Thu May 10 21:37:30 2018 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
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;