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