From ad06e987b147dc272e683a419ce5b4c39b2bd16b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 13 Mar 2015 09:38:16 +0000 Subject: [PATCH] The System V ABI for amd64 allows functions to use space in a 128 byte redzone below the stack pointer for scratch space and requires interrupt and signal frames to avoid overwriting it. However, EFI uses the Windows ABI which does not support this. As a result, interrupt handlers in EFI push their interrupt frames directly on top of the stack pointer. If the compiler used the red zone in a function in the EFI loader, then a device interrupt that occurred while that function was running could trash its local variables. In practice this happens fairly reliable when using gzipfs as an interrupt during decompression can trash the local variables in the inflate_table() function resulting in corrupted output or hangs. Fix this by disabling the redzone for amd64 EFI binaries. This requires building not only the loader but any libraries used by the loader without redzone support. Thanks to Jilles for pointing me at the redzone once I found the stack corruption. Differential Revision: https://reviews.freebsd.org/D2054 Reviewed by: imp MFC after: 2 weeks Sponsored by: Cisco Systems, Inc. --- lib/libstand/Makefile | 2 +- sys/boot/amd64/Makefile.inc | 2 +- sys/boot/efi/libefi/Makefile | 2 +- sys/boot/ficl/Makefile | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile index 4a1fa2cca72..a5a135f7fd3 100644 --- a/lib/libstand/Makefile +++ b/lib/libstand/Makefile @@ -28,7 +28,7 @@ CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float CFLAGS.gcc+= -mpreferred-stack-boundary=2 .endif .if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -fPIC +CFLAGS+= -fPIC -mno-red-zone .endif .if ${MACHINE} == "pc98" CFLAGS+= -Os diff --git a/sys/boot/amd64/Makefile.inc b/sys/boot/amd64/Makefile.inc index ee96a42abd8..7b10385928b 100644 --- a/sys/boot/amd64/Makefile.inc +++ b/sys/boot/amd64/Makefile.inc @@ -5,7 +5,7 @@ BINDIR?= /boot # See conf/kern.mk for the correct set of these -CFLAGS+= -ffreestanding +CFLAGS+= -ffreestanding -mno-red-zone CFLAGS+= -mno-mmx -mno-sse -mno-aes -mno-avx -msoft-float LDFLAGS+= -nostdlib diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index 3edeb22ea5a..bd753cff350 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -9,7 +9,7 @@ SRCS= delay.c efi_console.c efinet.c efipart.c errno.c handles.c \ SRCS+= nullconsole.c comconsole.c .if ${MACHINE_ARCH} == "amd64" -CFLAGS+= -fPIC +CFLAGS+= -fPIC -mno-red-zone .endif CFLAGS+= -I${.CURDIR}/../include CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH} diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile index 833cf99d851..15baae3f490 100644 --- a/sys/boot/ficl/Makefile +++ b/sys/boot/ficl/Makefile @@ -21,6 +21,9 @@ CFLAGS+= -ffreestanding CFLAGS+= -march=i386 CFLAGS.gcc+= -mpreferred-stack-boundary=2 .endif +.if ${MACHINE_CPUARCH} == "amd64" +CFLAGS+= -mno-red-zone +.endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float .endif