Makefile: Add build-time overlap check for programs loaded after coreboot
On non-x86 platforms, coreboot uses the memlayout.ld mechanism to statically allocate the different memory regions it needs and guarantees at build time that there are no dangerous overlaps between them. At the end of its (ramstage) execution, however, it usually loads a payload (and possibly other platform-specific components) that is not integrated into the coreboot build system and therefore cannot provide the same overlap guarantees through memlayout.ld. This creates a dangerous memory hazard where a new component could be loaded over memory areas that are still in use by the code-loading ramstage and lead to arbitrary memory corruption bugs. This patch fills this gap in our build-time correctness guarantees by adding the necessary checks as a new intermediate Makefile target on route to assembling the final image. It will parse the memory footprint information of the payload (and other platform-specific post-ramstage components) from CBFS and compare it to a list of memory areas known to be still in use during late ramstage, generating a build failure in case of a possible hazard. BUG=chrome-os-partner:48008 TEST=Built Oak while moving critical regions in the way of BL31 or the payload, observing the desired build-time errors. Built Nyan, Jerry and Falco without issues for good measure. Change-Id: I3ebd2c1caa4df959421265e26f9cab2c54909b68 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/13949 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
0819a47d14
commit
fffee873c8
46
Makefile.inc
46
Makefile.inc
|
@ -846,6 +846,52 @@ board_id-type := raw
|
||||||
$(obj)/board_id:
|
$(obj)/board_id:
|
||||||
printf $(CONFIG_BOARD_ID_STRING) > $@
|
printf $(CONFIG_BOARD_ID_STRING) > $@
|
||||||
|
|
||||||
|
# Ensure that no payload segment overlaps with memory regions used by ramstage
|
||||||
|
# (not for x86 since it can relocate itself in that case)
|
||||||
|
ifneq ($(CONFIG_ARCH_X86),y)
|
||||||
|
check-ramstage-overlap-regions := ramstage
|
||||||
|
check-ramstage-overlap-files :=
|
||||||
|
ifneq ($(CONFIG_PAYLOAD_NONE),y)
|
||||||
|
check-ramstage-overlap-files += $(CONFIG_CBFS_PREFIX)/payload
|
||||||
|
endif
|
||||||
|
|
||||||
|
# will output one or more lines of "<load address in hex> <memlen in decimal>"
|
||||||
|
cbfs-get-segments-cmd = $(CBFSTOOL) $(obj)/coreboot.pre print -v | sed -n \
|
||||||
|
'\%$(1)%,\%^[^ ]\{4\}%s% .*load: \(0x[0-9a-fA-F]*\),.*length: [0-9]*/\([0-9]*\).*%\1 \2%p'
|
||||||
|
|
||||||
|
ramstage-symbol-addr-cmd = $(OBJDUMP_ramstage) -t $(objcbfs)/ramstage.elf | \
|
||||||
|
sed -n '/ $(1)$$/s/^\([0-9a-fA-F]*\) .*/0x\1/p'
|
||||||
|
|
||||||
|
check-ramstage-overlaps: $(obj)/coreboot.pre
|
||||||
|
programs=$$($(foreach file,$(check-ramstage-overlap-files), \
|
||||||
|
$(call cbfs-get-segments-cmd,$(file)) ; )) ; \
|
||||||
|
regions=$$($(foreach region,$(check-ramstage-overlap-regions), \
|
||||||
|
echo $(region) ; \
|
||||||
|
$(call ramstage-symbol-addr-cmd,_$(region)) ; \
|
||||||
|
$(call ramstage-symbol-addr-cmd,_e$(region)) ; )) ; \
|
||||||
|
pstart= ; pend= ; \
|
||||||
|
for x in $$programs; do \
|
||||||
|
if [ -z $$pstart ]; then pstart=$$(($$x)) ; continue ; fi ; \
|
||||||
|
pend=$$(($$pstart + $$x)) ; \
|
||||||
|
rname= ; rstart= ; rend= ; \
|
||||||
|
for y in $$regions ; do \
|
||||||
|
if [ -z $$rname ]; then rname=$$y ; continue ; fi ; \
|
||||||
|
if [ -z $$rstart ]; then rstart=$$(($$y)) ; continue ; fi ; \
|
||||||
|
rend=$$(($$y)) ; \
|
||||||
|
if [ $$pstart -lt $$rend -a $$rstart -lt $$pend ]; then \
|
||||||
|
echo "ERROR: Ramstage region _$$rname overlapped by:" \
|
||||||
|
$(check-ramstage-overlap-files) ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi ; \
|
||||||
|
rname= ; rstart= ; rend= ; \
|
||||||
|
done ; \
|
||||||
|
pstart= ; pend= ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
INTERMEDIATE+=check-ramstage-overlaps
|
||||||
|
PHONY+=check-ramstage-overlaps
|
||||||
|
endif
|
||||||
|
|
||||||
junit.xml:
|
junit.xml:
|
||||||
echo "Building $(UTIL)"
|
echo "Building $(UTIL)"
|
||||||
echo '<?xml version="1.0" encoding="utf-8"?><testsuite>' > $@.tmp
|
echo '<?xml version="1.0" encoding="utf-8"?><testsuite>' > $@.tmp
|
||||||
|
|
|
@ -25,6 +25,10 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
|
||||||
CBFSTOOL_PRE1_OPTS = -m arm -s $(CONFIG_CBFS_SIZE)
|
CBFSTOOL_PRE1_OPTS = -m arm -s $(CONFIG_CBFS_SIZE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM),y)
|
||||||
|
check-ramstage-overlap-regions += postram_cbfs_cache stack ttb
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_ARM),y)
|
ifeq ($(CONFIG_ARCH_ARM),y)
|
||||||
subdirs-y += libgcc/
|
subdirs-y += libgcc/
|
||||||
subdirs-y += armv4/ armv7/
|
subdirs-y += armv4/ armv7/
|
||||||
|
|
|
@ -33,6 +33,10 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
|
||||||
CBFSTOOL_PRE1_OPTS = -m arm64 -s $(CONFIG_CBFS_SIZE)
|
CBFSTOOL_PRE1_OPTS = -m arm64 -s $(CONFIG_CBFS_SIZE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM64),y)
|
||||||
|
check-ramstage-overlap-regions += postram_cbfs_cache stack ttb
|
||||||
|
endif
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# bootblock
|
# bootblock
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -182,6 +186,8 @@ $(BL31_CBFS)-type := stage
|
||||||
$(BL31_CBFS)-compression := $(CBFS_COMPRESS_FLAG)
|
$(BL31_CBFS)-compression := $(CBFS_COMPRESS_FLAG)
|
||||||
cbfs-files-y += $(BL31_CBFS)
|
cbfs-files-y += $(BL31_CBFS)
|
||||||
|
|
||||||
|
check-ramstage-overlap-files += $(BL31_CBFS)
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARM64_USE_SECURE_OS),y)
|
ifeq ($(CONFIG_ARM64_USE_SECURE_OS),y)
|
||||||
|
|
||||||
SECURE_OS_FILE := $(CONFIG_ARM64_SECURE_OS_FILE)
|
SECURE_OS_FILE := $(CONFIG_ARM64_SECURE_OS_FILE)
|
||||||
|
@ -190,6 +196,8 @@ $(SECURE_OS_FILE_CBFS)-file := $(SECURE_OS_FILE)
|
||||||
$(SECURE_OS_FILE_CBFS)-type := stage
|
$(SECURE_OS_FILE_CBFS)-type := stage
|
||||||
cbfs-files-y += $(SECURE_OS_FILE_CBFS)
|
cbfs-files-y += $(SECURE_OS_FILE_CBFS)
|
||||||
|
|
||||||
|
check-ramstage-overlap-files += $(SECURE_OS_FILE_CBFS)
|
||||||
|
|
||||||
endif # CONFIG_ARM64_USE_SECURE_OS
|
endif # CONFIG_ARM64_USE_SECURE_OS
|
||||||
|
|
||||||
endif # CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE
|
endif # CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE
|
||||||
|
|
|
@ -22,6 +22,10 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPS),y)
|
||||||
CBFSTOOL_PRE1_OPTS = -m mips -s $(CONFIG_CBFS_SIZE)
|
CBFSTOOL_PRE1_OPTS = -m mips -s $(CONFIG_CBFS_SIZE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_RAMSTAGE_MIPS),y)
|
||||||
|
check-ramstage-overlap-regions += stack
|
||||||
|
endif
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# bootblock
|
# bootblock
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -19,6 +19,10 @@ riscv_flags = -I$(src)/arch/riscv/
|
||||||
|
|
||||||
riscv_asm_flags =
|
riscv_asm_flags =
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_RAMSTAGE_RISCV),y)
|
||||||
|
check-ramstage-overlap-regions += stack
|
||||||
|
endif
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
## bootblock
|
## bootblock
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
Loading…
Reference in New Issue