From: Udo Steinberg <udo@hypervisor.org>
To: u-boot@lists.denx.de
Subject: [BUG] U-Boot can overwrite itself with "bootelf" command
Date: Tue, 4 Oct 2022 21:36:04 +0200 [thread overview]
Message-ID: <20221004213604.64430b6e@X220.hypervisor.org> (raw)
Hi,
(please CC: me for replies, because I'm not subscribed to the list)
While debugging a U-Boot 2022.10 hang on an NXP i.MX8 board during execution
of the the "bootelf" command, I discovered the following general problem:
1) I have an aarch64 ELF binary that looks as follows:
Program Header:
LOAD off 0x00000000000000b0 vaddr 0x00000000ff000000 paddr 0x00000000ff000000 align 2**3
filesz 0x000000000000086c memsz 0x0000000000001000 flags rw-
LOAD off 0x0000000000001000 vaddr 0x0000ff8000001000 paddr 0x00000000ff001000 align 2**11
filesz 0x000000000000f4dc memsz 0x0000000000fff000 flags rw-
The second PHDR includes a rather large (~16MB) BSS that extends all the way
up to the very end of DRAM.
2) U-Boot relocates itself to the end of DRAM (as per bdinfo):
relocaddr = 0x00000000fff2c000
reloc off = 0x00000000bfd2c000
Build = 64-bit
3) When the ELF image from (1) is TFTP'd into memory (at some address <addr>) and then
launched via "bootelf -p <addr>", U-Boot does not detect the conflict with its own
image (2) and happily overwrites itself (causing the board to hang).
The code in question that does the overwriting is in lib/elf.c in
unsigned long load_elf64_image_phdr(unsigned long addr) here:
/* Load each program header */
for (i = 0; i < ehdr->e_phnum; ++i) {
void *dst = (void *)(ulong)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
debug("Loading phdr %i to 0x%p (%lu bytes)\n",
i, dst, (ulong)phdr->p_filesz);
if (phdr->p_filesz)
memcpy(dst, src, phdr->p_filesz);
if (phdr->p_filesz != phdr->p_memsz)
==> memset(dst + phdr->p_filesz, 0x00,
phdr->p_memsz - phdr->p_filesz);
flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
++phdr;
}
IMHO U-Boot should refuse to load anything into the address range where
U-Boot itself lives.
Cheers,
Udo
reply other threads:[~2022-10-05 16:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221004213604.64430b6e@X220.hypervisor.org \
--to=udo@hypervisor.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox