ELF notes have type and size fields in the elf_note header that need to be swabbed before use if the host endianness differs from the endianness of the ELF binary.
Signed-off-by: Ard Biesheuvel <a...@kernel.org> --- include/hw/elf_ops.h.inc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/include/hw/elf_ops.h.inc b/include/hw/elf_ops.h.inc index 9c35d1b9da..8b563db2a3 100644 --- a/include/hw/elf_ops.h.inc +++ b/include/hw/elf_ops.h.inc @@ -41,6 +41,13 @@ static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr) bswapSZs(&shdr->sh_entsize); } +static void glue(bswap_nhdr, SZ)(struct elf_note *nhdr) +{ + bswap32s(&nhdr->n_namesz); + bswap32s(&nhdr->n_descsz); + bswap32s(&nhdr->n_type); +} + static void glue(bswap_sym, SZ)(struct elf_sym *sym) { bswap32s(&sym->st_name); @@ -275,7 +282,8 @@ fail: static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, elf_word note_size, elf_word phdr_align, - elf_word elf_note_type) + elf_word elf_note_type, + int must_swab) { elf_word nhdr_size = sizeof(struct elf_note); elf_word elf_note_entry_offset = 0; @@ -287,6 +295,9 @@ static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, return NULL; } + if (must_swab) { + glue(bswap_nhdr, SZ)(nhdr); + } note_type = nhdr->n_type; while (note_type != elf_note_type) { nhdr_namesz = nhdr->n_namesz; @@ -306,6 +317,9 @@ static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, /* skip to the next ELF Note entry */ nhdr = (void *)nhdr + elf_note_entry_offset; + if (must_swab) { + glue(bswap_nhdr, SZ)(nhdr); + } note_type = nhdr->n_type; } @@ -603,7 +617,8 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd, nhdr = (struct elf_note *)data; assert(translate_opaque != NULL); nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align, - *(uint64_t *)translate_opaque); + *(uint64_t *)translate_opaque, + must_swab); if (nhdr != NULL) { elf_note_fn((void *)nhdr, (void *)&ph->p_align, SZ == 64); } -- 2.39.5