git: 39fdad34e220 - main - stand: impose 510,000 byte limit for /boot/loader and /boot/pxeldr

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 11 Aug 2022 03:31:36 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=39fdad34e220c52a433e78f20c8c39412429014e

commit 39fdad34e220c52a433e78f20c8c39412429014e
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-08-11 03:19:01 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-08-11 03:29:20 +0000

    stand: impose 510,000 byte limit for /boot/loader and /boot/pxeldr
    
    The BIOS method of booting imposes an absolute limit of 640k for the
    size of the program being run due to btx. In practice, this means that
    programs larger than about 500kiB will fail in odd ways as the stack /
    heap will overflow.
    
    Pick 510,000 as the cutoff line semi-arbitrarily. loader_lua is now
    almost too big and we want to break the build when it crosses this
    threshold. In my experience, below 500,000 always works, above 520,000
    always seems to fail with things getting bad somewhere between 512,000
    to 515,000. 510,000 is as close to the line as I think we can go, though
    experience may dictate we need to lower this in the future.
    
    This is at-best a stop-breakage until we have a better way to subset the
    boot loader for BIOS booting to allow better, more fined-tuned
    /boot/loaders for the many different environments they have to run
    in. This likely means we'll have a graphical loader than understands a
    few filesystmes for installation, and a non-graphical loader that
    understands the most filesystems possible for everything else in the
    future. Our build infrastructure needs some work before we can do that,
    however.
    
    At this late date, it likely isn't worth the efforts to move parts of
    the loader into high memory. There's a number of assumptions about where
    the stack is, where buffers reside, etc that are fulfilled when it lives
    in the first 640k that would need bounce buffers and/or other counter
    measures if we were to split it up. All BIOS calls are done in 16-bit
    mode with SEG:OFF addresses, requiring them to be in the first 640k of
    RAM. And nearly all machines in the last decade can boot with UEFI
    (though there's some exceptions, so it isn't worth killing outright
    yet).
    
    Sponsored by:           Netflix
    Reviewed by:            kevans
    Differential Revision:  https://reviews.freebsd.org/D36129
---
 stand/i386/loader/Makefile | 5 +++++
 stand/i386/pxeldr/Makefile | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile
index 3685281ffd2c..cde1513aac06 100644
--- a/stand/i386/loader/Makefile
+++ b/stand/i386/loader/Makefile
@@ -19,6 +19,8 @@ PROG=		${LOADER}.sym
 INTERNALPROG=
 NEWVERSWHAT?=	"bootstrap loader" x86
 VERSION_FILE=	${.CURDIR}/../loader/version
+LOADERSIZE=	510000		# Largest known safe size
+
 
 .PATH:		${BOOTSRC}/i386/loader
 
@@ -79,9 +81,12 @@ CFLAGS+=	-I${BOOTSRC}/i386
 8x16.c: ${SRCTOP}/contrib/terminus/ter-u16b.bdf
 	vtfontcvt -f compressed-source -o ${.TARGET} ${.ALLSRC}
 
+
 ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
 	btxld -v -f elf -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \
 		-b ${BTXKERN} ${LOADER}.bin
+	@set -- `${SIZE} ${.TARGET} | tail -1` ; x=$$((${LOADERSIZE}-$$4)); \
+	    echo "$$x bytes available"; test $$x -ge 0
 
 ${LOADER}.bin: ${LOADER}.sym
 	${STRIPBIN} -R .comment -R .note -o ${.TARGET} ${.ALLSRC}
diff --git a/stand/i386/pxeldr/Makefile b/stand/i386/pxeldr/Makefile
index a44dc0de2885..f8bc1eae9a31 100644
--- a/stand/i386/pxeldr/Makefile
+++ b/stand/i386/pxeldr/Makefile
@@ -13,6 +13,7 @@ BOOT=	pxeboot
 LDR=	pxeldr
 ORG=	0x7c00
 LOADER=	loader
+PXELDRSIZE= 510000		# Largest known safe size
 
 .if defined(BOOT_PXELDR_PROBE_KEYBOARD)
 CFLAGS+=-DPROBE_KEYBOARD
@@ -41,5 +42,7 @@ CLEANFILES+= ${LOADER}
 ${LOADER}: ${LOADERBIN} ${BTXLDR} ${BTXKERN}
 	btxld -v -f elf -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \
 	    -b ${BTXKERN} ${LOADERBIN}
+	@set -- `${SIZE} ${.TARGET} | tail -1` ; x=$$((${PXELDRSIZE}-$$4)); \
+	    echo "$$x bytes available"; test $$x -ge 0
 
 .include <bsd.prog.mk>