100 lines
3.4 KiB
Diff
100 lines
3.4 KiB
Diff
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 <mark.hatle@windriver.com>
|
|
|
|
Index: rpm-5.4.9/tools/debugedit.c
|
|
===================================================================
|
|
--- rpm-5.4.9.orig/tools/debugedit.c
|
|
+++ rpm-5.4.9/tools/debugedit.c
|
|
@@ -1432,21 +1432,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 };
|
|
-
|
|
- 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)
|
|
+ } u1, u2;
|
|
+ Elf_Data src = { .d_version = EV_CURRENT, .d_buf = &u1 };
|
|
+ Elf_Data dest = { .d_version = EV_CURRENT, .d_buf = &u2 };
|
|
+
|
|
+ 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",
|
|
@@ -1454,29 +1457,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)
|