From 2755e378483a072efab051c7730e5240161ec393 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 31 Dec 2012 10:08:34 +0000 Subject: [PATCH] [FREELDR] Implement MmCheckFreeldrImageFile() to check that freeldr was properly compiled and loaded. svn path=/trunk/; revision=58066 --- .../boot/freeldr/freeldr/arch/i386/i386bug.c | 8 ---- reactos/boot/freeldr/freeldr/debug.c | 10 ++++ .../freeldr/include/arch/pc/x86common.h | 1 + reactos/boot/freeldr/freeldr/include/debug.h | 15 ++++++ reactos/boot/freeldr/freeldr/include/mm.h | 7 +++ reactos/boot/freeldr/freeldr/mm/meminit.c | 47 +++++++++++++++++++ 6 files changed, 80 insertions(+), 8 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c b/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c index 260e39dd630..4ea6876b37f 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c @@ -171,14 +171,6 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST InstructionPointer[6], InstructionPointer[7]); } -char *BugCodeStrings[] = -{ - "TEST_BUGCHECK", - "MISSING_HARDWARE_REQUIREMENTS", -}; - -ULONG_PTR BugCheckInfo[5]; - void NTAPI FrLdrBugCheckEx( diff --git a/reactos/boot/freeldr/freeldr/debug.c b/reactos/boot/freeldr/freeldr/debug.c index 21b78ca2918..5ac8e10fbd0 100644 --- a/reactos/boot/freeldr/freeldr/debug.c +++ b/reactos/boot/freeldr/freeldr/debug.c @@ -427,3 +427,13 @@ RtlAssert(IN PVOID FailedAssertion, DbgBreakPoint(); } + +char *BugCodeStrings[] = +{ + "TEST_BUGCHECK", + "MISSING_HARDWARE_REQUIREMENTS", + "FREELDR_IMAGE_CORRUPTION", +}; + +ULONG_PTR BugCheckInfo[5]; + diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h index 91f8c420a0a..e681390bc61 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h @@ -23,6 +23,7 @@ #define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFSIZE PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */ +#define MAX_FREELDR_PE_SIZE (DISKREADBUFFER - FREELDR_PE_BASE) /* These addresses specify the realmode "BSS section" layout */ #define BSS_RealModeEntry (BSS_START + 0) diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index 16d04cc1780..7ab94d0491f 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -120,4 +120,19 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr); #endif // DBG +void +NTAPI +FrLdrBugCheck(ULONG BugCode); + +/* Bugcheck codes */ +enum _FRLDR_BUGCHECK_CODES +{ + TEST_BUGCHECK, + MISSING_HARDWARE_REQUIREMENTS, + FREELDR_IMAGE_CORRUPTION, +}; + +extern char *BugCodeStrings[]; +extern ULONG_PTR BugCheckInfo[5]; + #endif // defined __DEBUG_H diff --git a/reactos/boot/freeldr/freeldr/include/mm.h b/reactos/boot/freeldr/freeldr/include/mm.h index a453a284770..7b6ed61566a 100644 --- a/reactos/boot/freeldr/freeldr/include/mm.h +++ b/reactos/boot/freeldr/freeldr/include/mm.h @@ -19,6 +19,13 @@ #pragma once +extern char __ImageBase; +#ifdef __GNUC__ +#define FREELDR_SECTION_COUNT 3 +#else +#define FREELDR_SECTION_COUNT 1 +#endif + typedef struct _FREELDR_MEMORY_DESCRIPTOR { TYPE_OF_MEMORY MemoryType; diff --git a/reactos/boot/freeldr/freeldr/mm/meminit.c b/reactos/boot/freeldr/freeldr/mm/meminit.c index 7794f6f1639..5a8a25d4d05 100644 --- a/reactos/boot/freeldr/freeldr/mm/meminit.c +++ b/reactos/boot/freeldr/freeldr/mm/meminit.c @@ -163,6 +163,47 @@ ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR* Current) } +BOOLEAN +MmCheckFreeldrImageFile() +{ + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_FILE_HEADER FileHeader; + PIMAGE_OPTIONAL_HEADER OptionalHeader; + + /* Get the NT headers */ + NtHeaders = RtlImageNtHeader(&__ImageBase); + if (!NtHeaders) + { + ERR("Coult not get NtHeaders!\n"); + return FALSE; + } + + /* Check the file header */ + FileHeader = &NtHeaders->FileHeader; + if ((FileHeader->Machine != IMAGE_FILE_MACHINE_NATIVE) || + (FileHeader->NumberOfSections != FREELDR_SECTION_COUNT) || + (FileHeader->PointerToSymbolTable != 0) || + (FileHeader->NumberOfSymbols != 0) || + (FileHeader->NumberOfSymbols != 0) || + (FileHeader->SizeOfOptionalHeader != 0xE0)) + { + return FALSE; + } + + /* Check the optional header */ + OptionalHeader = &NtHeaders->OptionalHeader; + if ((OptionalHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) || + (OptionalHeader->Subsystem != 1) || // native + (OptionalHeader->ImageBase != FREELDR_PE_BASE) || + (OptionalHeader->SizeOfImage > MAX_FREELDR_PE_SIZE) || + (OptionalHeader->SectionAlignment != OptionalHeader->FileAlignment)) + { + return FALSE; + } + + return TRUE; +} + BOOLEAN MmInitializeMemoryManager(VOID) { #if DBG @@ -171,6 +212,12 @@ BOOLEAN MmInitializeMemoryManager(VOID) TRACE("Initializing Memory Manager.\n"); + /* Check the freeldr binary */ + if (!MmCheckFreeldrImageFile()) + { + FrLdrBugCheck(FREELDR_IMAGE_CORRUPTION); + } + BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount); #if DBG