https://git.reactos.org/?p=reactos.git;a=commitdiff;h=14563105034fc009bb764e65e40a8158644028a7
commit 14563105034fc009bb764e65e40a8158644028a7 Author: Serge Gautherie <reactos-git_serge_171...@gautherie.fr> AuthorDate: Mon Oct 9 01:40:22 2017 +0200 [FREELDR] PcMemGetBiosMemoryMap(): Add checks for entry sizes and bare handling of error case. CORE-13332 --- boot/freeldr/freeldr/arch/i386/pcmem.c | 23 +++++++++++++++++++++++ boot/freeldr/freeldr/include/arch/pc/pcbios.h | 5 +++++ 2 files changed, 28 insertions(+) diff --git a/boot/freeldr/freeldr/arch/i386/pcmem.c b/boot/freeldr/freeldr/arch/i386/pcmem.c index aa5b18d226..9b0997ebf5 100644 --- a/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -293,6 +293,29 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi goto nextRange; } + /* Extra safety: unexpected entry length. + * All in-between values are valid too, as x86 is little-indian + * and only lower byte is used per ACPI 6.2-A. + */ + if (Regs.x.ecx < RTL_SIZEOF_THROUGH_FIELD(BIOS_MEMORY_MAP, Type) || + Regs.x.ecx > sizeof(BIOS_MEMORY_MAP)) + { + ERR("Int 15h AX=E820h returned an invalid entry length! (would-be-PcBiosMapCount = %lu, Entry length = (%Iu <=) %lu (<= %Iu))\n\n", + PcBiosMapCount, RTL_SIZEOF_THROUGH_FIELD(BIOS_MEMORY_MAP, Type), Regs.x.ecx, sizeof(BIOS_MEMORY_MAP)); + /* Warn user, unless wrong case is "first and not too big entry", which is otherwise harmless. */ + if (PcBiosMapCount > 0 || Regs.x.ecx > sizeof(BIOS_MEMORY_MAP)) + { + ASSERTMSG("Int 15h AX=E820h returned an invalid entry length!", FALSE); + } + /* We keep previous entries (if any), but do not dare trying next entries. + * We assume these entries are good to use as is. If they are not, we are in trouble... + * (And don't ask what happens if BIOS actually overflowed our entry buffer...) + * + * FIXME: Safer = revert previous entries, Safest = blacklist this BIOS. + */ + break; + } + /* Copy data to global buffer */ RtlCopyMemory(&PcBiosMemoryMap[PcBiosMapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx); diff --git a/boot/freeldr/freeldr/include/arch/pc/pcbios.h b/boot/freeldr/freeldr/include/arch/pc/pcbios.h index ecfaf90b2a..b60df0b122 100644 --- a/boot/freeldr/freeldr/include/arch/pc/pcbios.h +++ b/boot/freeldr/freeldr/include/arch/pc/pcbios.h @@ -19,6 +19,11 @@ typedef struct ULONG Reserved; } BIOS_MEMORY_MAP, *PBIOS_MEMORY_MAP; +/* Int 15h AX=E820h Entry minimal size. */ +C_ASSERT(FIELD_OFFSET(BIOS_MEMORY_MAP, Reserved) == 20); +/* Int 15h AX=E820h Entry maximal size. */ +C_ASSERT(sizeof(BIOS_MEMORY_MAP) == 24); + /* FIXME: Should be moved to NDK, and respective ACPI header files */ typedef struct _ACPI_BIOS_DATA {