From 69888bc7fca5a55dca5282b02eef165e2c61b3ef Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 15 Apr 2025 09:37:28 +0200 Subject: [PATCH] util/cbfstool/amdcompress: Bail out on invalid ELF Ensure that only one PT_LOAD segment is inside the input ELF as the tool only expects and support one PT_LOAD segment. Instead of silently discarding all other PT_LOAD segments than the first throw an error. Change-Id: I90cfc8b9dd0b5e8060880790e5ff0ce73843943b Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/87315 Reviewed-by: Matt DeVillier Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) --- .../common/block/cpu/noncar/memlayout_x86.ld | 5 +++-- util/cbfstool/amdcompress.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld index 4372de8760..024afbe7e5 100644 --- a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld +++ b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld @@ -137,8 +137,9 @@ SECTIONS { * .text and .reset breaks the integrity, as .bss or .data might get modified. * * Enable ENV_SEPARATE_DATA_AND_BSS for AMD's bootblock and mark as - * data_segment to place it in the second PT_LOAD area. AMDCOMPRESS will ignore - * the second PT_LOAD area and discard it. + * data_segment to place it in the second PT_LOAD area. The second PT_LOAD area + * must be removed using objcopy since AMDCOMPRESS doesn't support multiple + * PT_LOAD segments. */ . = BOOTBLOCK_ADDR & ~(16 - 1); .data . : { diff --git a/util/cbfstool/amdcompress.c b/util/cbfstool/amdcompress.c index 76089ea340..9b778cbc07 100644 --- a/util/cbfstool/amdcompress.c +++ b/util/cbfstool/amdcompress.c @@ -75,12 +75,28 @@ static int do_file(char *name, size_t *size, int oflag) } static int parse_elf_to_xip_ram(const struct buffer *input, - struct buffer *output) + struct buffer *output) { struct parsed_elf pelf; + const Elf64_Phdr *phdr; if (parse_elf(input, &pelf, ELF_PARSE_ALL)) return 1; + + /* Validate ELF. Expect only on PT_LOAD program header at index 0. */ + for (int i = 0; i < pelf.ehdr.e_phnum; i++) { + phdr = &pelf.phdr[i]; + /* Expect PT_LOAD on first entry */ + if (i == 0 && (phdr->p_type != PT_LOAD || !phdr->p_memsz)) { + printf("\tProgram header #0 is invalid.\n"); + } + /* Expect not to find more PT_LOAD program headers */ + if (i > 0 && phdr->p_type == PT_LOAD && phdr->p_memsz) { + printf("\tMultiple program headers found, but only one is supported!\n"); + return 1; + } + } + if (buffer_create(output, pelf.phdr->p_filesz, "") != 0) return 1;