During the recalculation of the buildid, it's necessary to change the word back to the original endian. However, if we do this in-place, we've also affected the headers that we're also working on. The side effect of this is we can no longer rely on 'sh_type' as it may have been changed. This patch ensures that any time we translate the loaded data to the machine format, we only do it in a backup copy and never the original copy. Note: in all other places a backup copy was used, just not buildid processing. Also the process (...) function was modified to verify the data is not NULL as well. This is an extra check and is not strictly necessary. Upstream-Status: Pending Signed-off-by: Mark Hatle Index: rpm-5.4.14/tools/debugedit.c =================================================================== --- rpm-5.4.14.orig/tools/debugedit.c +++ rpm-5.4.14/tools/debugedit.c @@ -1445,21 +1445,24 @@ handle_build_id (DSO *dso, Elf_Data *bui auto inline void process (const void *data, size_t size) { memchunk chunk = { .data = (void *) data, .size = size }; - hashFunctionContextUpdateMC (&ctx, &chunk); + if (data != NULL && size != 0) + hashFunctionContextUpdateMC (&ctx, &chunk); } union { GElf_Ehdr ehdr; GElf_Phdr phdr; GElf_Shdr shdr; - } u; - Elf_Data x = { .d_version = EV_CURRENT, .d_buf = &u }; + } u1, u2; + Elf_Data src = { .d_version = EV_CURRENT, .d_buf = &u1 }; + Elf_Data dest = { .d_version = EV_CURRENT, .d_buf = &u2 }; - x.d_type = ELF_T_EHDR; - x.d_size = sizeof u.ehdr; - u.ehdr = dso->ehdr; - u.ehdr.e_phoff = u.ehdr.e_shoff = 0; - if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL) + src.d_type = ELF_T_EHDR; + src.d_size = sizeof u1.ehdr; + dest.d_size = sizeof u2.ehdr; + u1.ehdr = dso->ehdr; + u1.ehdr.e_phoff = u1.ehdr.e_shoff = 0; + if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) { bad: fprintf (stderr, "Failed to compute header checksum: %s\n", @@ -1467,29 +1470,31 @@ handle_build_id (DSO *dso, Elf_Data *bui exit (1); } - x.d_type = ELF_T_PHDR; - x.d_size = sizeof u.phdr; + src.d_type = ELF_T_PHDR; + src.d_size = sizeof u1.phdr; + dest.d_size = sizeof u2.phdr; for (i = 0; i < dso->ehdr.e_phnum; ++i) { - if (gelf_getphdr (dso->elf, i, &u.phdr) == NULL) + if (gelf_getphdr (dso->elf, i, &u1.phdr) == NULL) goto bad; - if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL) + if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) goto bad; - process (x.d_buf, x.d_size); + process (dest.d_buf, dest.d_size); } - x.d_type = ELF_T_SHDR; - x.d_size = sizeof u.shdr; + src.d_type = ELF_T_SHDR; + src.d_size = sizeof u1.shdr; + dest.d_size = sizeof u2.shdr; for (i = 0; i < dso->ehdr.e_shnum; ++i) if (dso->scn[i] != NULL) { - u.shdr = dso->shdr[i]; - u.shdr.sh_offset = 0; - if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL) + u1.shdr = dso->shdr[i]; + u1.shdr.sh_offset = 0; + if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) goto bad; - process (x.d_buf, x.d_size); + process (dest.d_buf, dest.d_size); - if (u.shdr.sh_type != SHT_NOBITS) + if (u1.shdr.sh_type != SHT_NOBITS) { Elf_Data *d = elf_rawdata (dso->scn[i], NULL); if (d == NULL)