rpm: Fix debugedit buildid processing

[ YOCTO #4089 ]

When constructing a new buildid, the items being hashed need to be
returned to their native endian.  In the process we were munging
the sh_type field that we relied on to determine if a section was
loadable or not.  The patch avoids this behavior by only modifying
a copy of the local endian data.

(From OE-Core rev: ac4d2d44c88cace8dbce0c8e7df3fd1f2ed244b4)

Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Mark Hatle 2013-03-25 22:35:13 -05:00 committed by Richard Purdie
parent 21288ac9da
commit 6da3aca59b
1 changed files with 78 additions and 14 deletions

View File

@ -1,19 +1,15 @@
There are cases, especially on PPC and MIPS, where the data address
returned is 0, but the size is not 0.
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.
It appears to happen when the sections headers are similar to:
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.
[21] .data PROGBITS 000239c0 0139c0 000010 00 WA 0 0 8
[22] .got PROGBITS 000239d0 0139d0 000014 04 WAX 0 0 4
[23] .plt NOBITS 000239e4 0139e4 000234 00 WAX 0 0 4
[24] .bss NOBITS 00023c18 0139e4 0001c8 00 WA 0 0 8
[25] .comment PROGBITS 00000000 0139e4 000011 01 MS 0 0 1
[26] .debug_aranges PROGBITS 00000000 0139f8 000d68 00 0 0 8
Note: in all other places a backup copy was used, just not buildid processing.
Sections 23 and 24 (.plt and .bss) which are NOBITS have a loaded data address
of 0, but a size != 0.
This could be a bug in libelf...
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
@ -23,7 +19,7 @@ Index: rpm-5.4.9/tools/debugedit.c
===================================================================
--- rpm-5.4.9.orig/tools/debugedit.c
+++ rpm-5.4.9/tools/debugedit.c
@@ -1434,7 +1434,8 @@ handle_build_id (DSO *dso, Elf_Data *bui
@@ -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 };
@ -33,3 +29,71 @@ Index: rpm-5.4.9/tools/debugedit.c
}
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)