[FREELDR] PcMemGetBiosMemoryMap(): Add checks for entry sizes and bare handling of... 42/head
authorSerge Gautherie <reactos-git_serge_171003@gautherie.fr>
Sun, 8 Oct 2017 23:40:22 +0000 (01:40 +0200)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 18 Nov 2017 20:54:14 +0000 (21:54 +0100)
boot/freeldr/freeldr/arch/i386/pcmem.c
boot/freeldr/freeldr/include/arch/pc/pcbios.h

index aa5b18d..9b0997e 100644 (file)
@@ -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);
 
index ecfaf90..b60df0b 100644 (file)
@@ -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
 {