Some machines (e.g. some Intel Macs) have a EFI memory map with more than
authorkettenis <kettenis@openbsd.org>
Sun, 23 May 2021 20:30:42 +0000 (20:30 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 23 May 2021 20:30:42 +0000 (20:30 +0000)
64 entries.  Instead of writing beyond the array that we use to construct
a BIOS compatible memory map, check that we don't overflow the array and
print a message if we do.  Bump the size of the array from 64 to 128
entries.

Issue reported and debugged by David N. Arnold.
Further input from yasuoka@

ok deraadt@ (earlier version) and yasuaka@

sys/arch/amd64/stand/efiboot/conf.c
sys/arch/amd64/stand/efiboot/efiboot.c

index 3304a44..6d2cde1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.34 2021/03/17 05:41:34 yasuoka Exp $       */
+/*     $OpenBSD: conf.c,v 1.35 2021/05/23 20:30:42 kettenis Exp $      */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff
@@ -40,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.57";
+const char version[] = "3.58";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
index 4d23460..f00c0f2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efiboot.c,v 1.36 2020/10/30 19:39:00 kettenis Exp $   */
+/*     $OpenBSD: efiboot.c,v 1.37 2021/05/23 20:30:42 kettenis Exp $   */
 
 /*
  * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -58,7 +58,7 @@ u_long                         efi_loadaddr;
 int     efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
 int     efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
 static void     efi_heap_init(void);
-static void     efi_memprobe_internal(void);
+static int      efi_memprobe_internal(void);
 static void     efi_video_init(void);
 static void     efi_video_reset(void);
 static EFI_STATUS
@@ -281,7 +281,7 @@ efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn)
 /***********************************************************************
  * Memory
  ***********************************************************************/
-bios_memmap_t           bios_memmap[64];
+bios_memmap_t           bios_memmap[128];
 bios_efiinfo_t          bios_efiinfo;
 
 static void
@@ -304,6 +304,7 @@ efi_memprobe(void)
        EFI_STATUS       status;
        EFI_PHYSICAL_ADDRESS
                         addr = 0x10000000ULL;  /* Below 256MB */
+       int              error;
 
        status = EFI_CALL(BS->AllocatePages, AllocateMaxAddress, EfiLoaderData,
            EFI_SIZE_TO_PAGES(KERN_LOADSPACE_SIZE), &addr);
@@ -312,7 +313,7 @@ efi_memprobe(void)
        efi_loadaddr = addr;
 
        printf(" mem[");
-       efi_memprobe_internal();
+       error = efi_memprobe_internal();
        for (bm = bios_memmap; bm->type != BIOS_MAP_END; bm++) {
                if (bm->type == BIOS_MAP_FREE && bm->size > 12 * 1024) {
                        if (n++ != 0)
@@ -323,10 +324,12 @@ efi_memprobe(void)
                                printf("%uK", bm->size / 1024);
                }
        }
+       if (error == E2BIG)
+               printf(" overflow");
        printf("]");
 }
 
-static void
+static int
 efi_memprobe_internal(void)
 {
        EFI_STATUS               status;
@@ -335,6 +338,7 @@ efi_memprobe_internal(void)
        EFI_MEMORY_DESCRIPTOR   *mm0, *mm;
        int                      i, n;
        bios_memmap_t           *bm, bm0;
+       int                      error = 0;
 
        cnvmem = extmem = 0;
        bios_memmap[0].type = BIOS_MAP_END;
@@ -395,6 +399,10 @@ efi_memprobe_internal(void)
                        }
                }
                if (bm->type == BIOS_MAP_END) {
+                       if (bm == &bios_memmap[nitems(bios_memmap) - 1]) {
+                               error = E2BIG;
+                               break;
+                       }
                        *bm = bm0;
                        (++bm)->type = BIOS_MAP_END;
                }
@@ -412,6 +420,8 @@ efi_memprobe_internal(void)
        bios_efiinfo.mmap_desc_size = mmsiz;
        bios_efiinfo.mmap_size = siz;
        bios_efiinfo.mmap_start = (uintptr_t)mm0;
+
+       return error;
 }
 
 /***********************************************************************