From: JianfengA.Zhu@sony.com Date: Wed, 7 Aug 2024 02:20:07 +0000 (+0000) Subject: lib: elf: Fix bootelf -p crash issue X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=37dc8c2e98dafd10520207382c17a2ff234c20b7;p=u-boot.git lib: elf: Fix bootelf -p crash issue Do not load and flush segments whose program header type is not PT_LOAD to avoid crash happen. bootelf will load all program headers and then flush cache. Since PT_GNU_STACK start address is 0x0, crash happens when it flushes PT_GNU_STACK area for target that memory cannot be accessed from address 0x0. crash call stack: ==================================================================== bootelf -p |-> do_bootelf (cmd/elf.c) |-> load_elf_image_phdr (lib/elf.c) /* Load each program header */ |-> for (i = 0; i < ehdr->e_phnum; ++i) { /* e_phnum is 2 */ |-> flush_cache(start=0, size=0) (arch/arm/lib/cache.c) (*1) |-> flush_dcache_range(start=0, 0); (arch/arm/cpu/armv8/cache_v8.c) |-> __asm_flush_dcache_range(start=0, 0) (arch/arm/cpu/armv8/cache.S) |-> /* clean & invalidate data or unified cache */ |-> dc civac, x0 <<== crash happen x0:start=0 ==================================================================== *1 Here the p_paddr and p_filesz of the GNU_STACK program are 0. hello_world elf image program headers ==================================================================== Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000080ff0000 0x0000000080ff0000 0x0000000000010390 0x0000000000010390 R E 0x10000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10 Section to Segment mapping: Segment Sections... 00 .text .rodata .eh_frame 01 ==================================================================== bootelf -p crash error log ==================================================================== bootelf -p 0x80f00000 "Synchronous Abort" handler, esr 0x96000147, far 0x0 elr: 000000008f6035bc lr : 000000008f66ff54 (reloc) elr: 00000000bd9475bc lr : 00000000bd9b3f54 x0 : 0000000000000000 x1 : 0000000000000000 x2 : 0000000000000040 x3 : 000000000000003f x4 : 0000000081000390 x5 : 00000000bd12da98 x6 : 0000000000000010 x7 : 0000000000000010 x8 : 000000000000000a x9 : 00000000bd156b30 x10: 00000000bd1526e0 x11: 0000000000000000 x12: 0000000000000004 x13: 00000000bda00000 x14: 00000000ffffffff x15: 00000000bd12dab7 x16: 00000000bd957b14 x17: 0000000000000000 x18: 00000000bd13fd90 x19: 0000000080f000b0 x20: 0000000080f00000 x21: 0000000000000002 x22: 0000000000000000 x23: 0000000000000003 x24: 00000000bd9eacc0 x25: 0000000000000000 x26: 0000000000000000 x27: 0000000000000000 x28: 00000000bd154c80 x29: 00000000bd12da70 Code: d2800082 9ac32042 d1000443 8a230000 (d50b7e20) ==================================================================== Signed-off-by: Jianfeng Zhu Reviewed-by: Jacky Cao Reviewed-by: Toyama, Yoshihiro --- diff --git a/lib/elf.c b/lib/elf.c index dc13935e10..28ec87b8e4 100644 --- a/lib/elf.c +++ b/lib/elf.c @@ -90,6 +90,10 @@ unsigned long load_elf64_image_phdr(unsigned long addr) void *dst = (void *)(ulong)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + /* Only load PT_LOAD program header */ + if (phdr->p_type != PT_LOAD) + continue; + debug("Loading phdr %i to 0x%p (%lu bytes)\n", i, dst, (ulong)phdr->p_filesz); if (phdr->p_filesz) @@ -205,6 +209,10 @@ unsigned long load_elf_image_phdr(unsigned long addr) void *dst = (void *)(uintptr_t)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + /* Only load PT_LOAD program header */ + if (phdr->p_type != PT_LOAD) + continue; + debug("Loading phdr %i to 0x%p (%i bytes)\n", i, dst, phdr->p_filesz); if (phdr->p_filesz)