[PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes

Ard Biesheuvel posted 2 patches 1 month, 3 weeks ago
[PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes
Posted by Ard Biesheuvel 1 month, 3 weeks ago
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 <ardb@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