https://git.reactos.org/?p=reactos.git;a=commitdiff;h=177ae91bf63810daae17f1...
commit 177ae91bf63810daae17f15bb21be16592c485a1 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Sat Mar 28 14:28:49 2020 +0100 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Sun Mar 29 21:27:38 2020 +0200
[RTL] Introduce RtlpImageNtHeader, which implements the required functionality. ntdll and ntoskrnl now have a wrapper for this, with SEH. This protects the function against malformed / bad images, whilst still being able to use the code in freeldr et al. Idea from Thomas. CORE-14857 --- boot/environ/CMakeLists.txt | 1 + boot/environ/lib/rtl/libsupp.c | 39 ++++++++++++++++++++++++++++++ boot/freeldr/freeldr/lib/rtl/libsupp.c | 27 +++++++++++++++++++++ dll/ntdll/rtl/libsupp.c | 43 ++++++++++++++++++++++++++++++++++ dll/win32/kernel32/client/loader.c | 13 ++-------- ntoskrnl/rtl/libsupp.c | 43 ++++++++++++++++++++++++++++++++++ sdk/lib/rtl/image.c | 3 +-- 7 files changed, 156 insertions(+), 13 deletions(-)
diff --git a/boot/environ/CMakeLists.txt b/boot/environ/CMakeLists.txt index f79136c42ea..daa621ac216 100644 --- a/boot/environ/CMakeLists.txt +++ b/boot/environ/CMakeLists.txt @@ -20,6 +20,7 @@ list(APPEND BOOTLIB_SOURCE lib/misc/resource.c lib/misc/font.c lib/misc/rtlcompat.c + lib/rtl/libsupp.c lib/firmware/fwutil.c lib/firmware/efi/firmware.c lib/mm/mm.c diff --git a/boot/environ/lib/rtl/libsupp.c b/boot/environ/lib/rtl/libsupp.c new file mode 100644 index 00000000000..257b859893a --- /dev/null +++ b/boot/environ/lib/rtl/libsupp.c @@ -0,0 +1,39 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Library + * FILE: boot/environ/lib/rtl/libsupp.c + * PURPOSE: RTL Support Routines + * PROGRAMMER: Mark Jansen (mark.jansen@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "bl.h" + +/* FUNCTIONS *****************************************************************/ + +/* Ldr access to IMAGE_NT_HEADERS without SEH */ + +/* Rtl SEH-Free version of this */ +NTSTATUS +NTAPI +RtlpImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders); + + +/* + * @implemented + */ +NTSTATUS +NTAPI +RtlImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders) +{ + return RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders); +} diff --git a/boot/freeldr/freeldr/lib/rtl/libsupp.c b/boot/freeldr/freeldr/lib/rtl/libsupp.c index eb9bc2acd13..585164d03f3 100644 --- a/boot/freeldr/freeldr/lib/rtl/libsupp.c +++ b/boot/freeldr/freeldr/lib/rtl/libsupp.c @@ -57,3 +57,30 @@ RtlpSafeCopyMemory( RtlCopyMemory(Destination, Source, Length); return STATUS_SUCCESS; } + +/* Ldr access to IMAGE_NT_HEADERS without SEH */ + +/* Rtl SEH-Free version of this */ +NTSTATUS +NTAPI +RtlpImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders); + + +/* + * @implemented + */ +NTSTATUS +NTAPI +RtlImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders) +{ + return RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders); +} + diff --git a/dll/ntdll/rtl/libsupp.c b/dll/ntdll/rtl/libsupp.c index 94c6f0e5b00..c16f243cec4 100644 --- a/dll/ntdll/rtl/libsupp.c +++ b/dll/ntdll/rtl/libsupp.c @@ -505,6 +505,49 @@ RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index) return NULL; }
+/* Ldr SEH-Protected access to IMAGE_NT_HEADERS */ + +/* Rtl SEH-Free version of this */ +NTSTATUS +NTAPI +RtlpImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders); + + +/* + * @implemented + * @note: This is here, so that we do not drag SEH into rosload, freeldr and bootmgfw + */ +NTSTATUS +NTAPI +RtlImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders) +{ + NTSTATUS Status; + + /* Assume failure. This is also done in RtlpImageNtHeaderEx, but this is guarded by SEH. */ + if (OutHeaders != NULL) + *OutHeaders = NULL; + + _SEH2_TRY + { + Status = RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + return Status; +}
/* * Ldr Resource support code diff --git a/dll/win32/kernel32/client/loader.c b/dll/win32/kernel32/client/loader.c index ec4111470a3..93eb366a0f0 100644 --- a/dll/win32/kernel32/client/loader.c +++ b/dll/win32/kernel32/client/loader.c @@ -464,17 +464,8 @@ FreeLibrary(HINSTANCE hLibModule)
if (LDR_IS_DATAFILE(hLibModule)) { - // FIXME: This SEH should go inside RtlImageNtHeader instead - // See https://jira.reactos.org/browse/CORE-14857 - _SEH2_TRY - { - /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */ - NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1)); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - NtHeaders = NULL; - } _SEH2_END + /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */ + NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
if (NtHeaders) { diff --git a/ntoskrnl/rtl/libsupp.c b/ntoskrnl/rtl/libsupp.c index d461a795377..c1ded68d35c 100644 --- a/ntoskrnl/rtl/libsupp.c +++ b/ntoskrnl/rtl/libsupp.c @@ -691,6 +691,49 @@ RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index) return Entry; }
+/* Ldr SEH-Protected access to IMAGE_NT_HEADERS */ + +/* Rtl SEH-Free version of this */ +NTSTATUS +NTAPI +RtlpImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders); + +/* + * @implemented + * @note: This is here, so that we do not drag SEH into rosload, freeldr and bootmgfw + */ +NTSTATUS +NTAPI +RtlImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS *OutHeaders) +{ + NTSTATUS Status; + + /* Assume failure. This is also done in RtlpImageNtHeaderEx, but this is guarded by SEH. */ + if (OutHeaders != NULL) + *OutHeaders = NULL; + + _SEH2_TRY + { + Status = RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + return Status; +} + /* * Ldr Resource support code */ diff --git a/sdk/lib/rtl/image.c b/sdk/lib/rtl/image.c index 5629c775fde..5ae6f679f72 100644 --- a/sdk/lib/rtl/image.c +++ b/sdk/lib/rtl/image.c @@ -134,11 +134,10 @@ LdrVerifyMappedImageMatchesChecksum(
/* * @implemented - * @note This needs SEH (See https://jira.reactos.org/browse/CORE-14857) */ NTSTATUS NTAPI -RtlImageNtHeaderEx( +RtlpImageNtHeaderEx( _In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size,