https://git.reactos.org/?p=reactos.git;a=commitdiff;h=14563105034fc009bb764…
commit 14563105034fc009bb764e65e40a8158644028a7
Author: Serge Gautherie <reactos-git_serge_171003(a)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
{