> From: "David N. Arnold" <[email protected]>
> Date: Mon, 10 May 2021 18:28:28 -0400
>
> System description:
>
> 13-inch, Mid 2009 MacBook Pro (MacBookPro5,5) with memory upgraded to 8 GB.
>
> Observed behavior:
>
> On boot, system immediately hangs at:
>
> probing: pc0 mem[
>
> Steps to reproduce:
>
> - Boot from a USB installer of 6.9 (hangs)
> - Boot from a CD installer of 6.9 (works), install the system, and
> reboot (hangs)
> - Upgrade from 6.8 to 6.9 and reboot (hangs)
> - Compile the 6.8 version of the boot code with 6.9 and install on
> the EFI partition (hangs)
>
> Workaround:
>
> Copy the BOOTX64.EFI from 6.8 release to the EFI system partition.
>
> Diagnosis:
>
> I added some debug printf statements to the code and found that it was
> hanging at this line in src/sys/arch/amd64/stand/efiboot/efiboot.c:
>
> (++bm)->type = BIOS_MAP_END;
>
> This appears to be a buffer overrun on:
>
> bios_memmap_t bios_memmap[64];
>
> Updating to a size of 128 allows the machine to boot. With some
> additional debug statements, I found that it processes 204 records
> from GetMemoryMap into 74 entries in bios_memmap.
Nice bit of debugging!
> I'm not sure how a fixed size 64 was chosen, since the UEFI memory map
> of the system could be arbitrarily long, so I can't say how long this
> array needs to be to work on every system. At the very least, it
> should probably be doubled with some assertions and a panic if it runs
> out of room.
>
> I'm also not quite sure why the 6.8 copy of BOOTX64.EFI works, other
> than it is just happily clobbering memory. The fact that the 6.8
> version of the code fails when compiled on 6.9 makes me think maybe
> there is some checking added by the 6.9 compiler chain that detects
> the overrun and halts?
Pure luck probably.
Anyway, here is a diff that prevents the overrun and raises the number
of map entries to 128. Can you try this diff and confirm it works for
you?
Index: arch/amd64/stand/efiboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/conf.c,v
retrieving revision 1.34
diff -u -p -r1.34 conf.c
--- arch/amd64/stand/efiboot/conf.c 17 Mar 2021 05:41:34 -0000 1.34
+++ arch/amd64/stand/efiboot/conf.c 11 May 2021 20:44:15 -0000
@@ -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: arch/amd64/stand/efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
retrieving revision 1.36
diff -u -p -r1.36 efiboot.c
--- arch/amd64/stand/efiboot/efiboot.c 30 Oct 2020 19:39:00 -0000 1.36
+++ arch/amd64/stand/efiboot/efiboot.c 11 May 2021 20:44:15 -0000
@@ -281,7 +281,7 @@ efi_device_path_ncmp(EFI_DEVICE_PATH *dp
/***********************************************************************
* Memory
***********************************************************************/
-bios_memmap_t bios_memmap[64];
+bios_memmap_t bios_memmap[128];
bios_efiinfo_t bios_efiinfo;
static void
@@ -398,6 +398,8 @@ efi_memprobe_internal(void)
*bm = bm0;
(++bm)->type = BIOS_MAP_END;
}
+ if (bm == &bios_memmap[nitems(bios_memmap) - 1])
+ break;
}
for (bm = bios_memmap; bm->type != BIOS_MAP_END; bm++) {
if (bm->addr < IOM_BEGIN) /* Below memory hole */