| From 61f6cc8f80a3d67afeee619c2ab0fa47d8ac6bb1 Mon Sep 17 00:00:00 2001 |
| From: Kevin Cernekee <cernekee@chromium.org> |
| Date: Sat, 22 Oct 2016 22:31:46 -0700 |
| Subject: [PATCH 1/2] unstrip: Don't try to use unstripped .symtab with |
| stripped .strtab |
| |
| Prematurely matching up the stripped and unstripped .strtab sections |
| in the "Match each debuginfo" loop can lead to a case where sec->outscn |
| gets populated for the stripped .strtab, which we normally want to |
| ignore. This causes the .strtab override in the "Make sure each main |
| file section" loop to be skipped, so the code winds up using indices |
| from the unstripped .symtab to look up strings in the stripped .strtab. |
| This returns incorrect strings for a little while, and then fails |
| catastrophically when it tries to read past the end of the (smaller) |
| stripped file's .strtab section: |
| |
| eu-unstrip: invalid string offset in symbol [1589] |
| |
| Fix this by adding logic to the "Match each debuginfo" loop to |
| treat the unstripped .strtab, .shstrtab, and .symtab sections |
| essentially the same way. |
| |
| The new logic will break if the .strtab section shows up earlier than |
| the .symtab section. We will assume this never happens in practice. |
| |
| Signed-off-by: Kevin Cernekee <cernekee@chromium.org> |
| --- |
| |
| diff --git a/src/unstrip.c b/src/unstrip.c |
| index 3bf4b192b5db..cc3dcb26611a 100644 |
| --- a/src/unstrip.c |
| +++ b/src/unstrip.c |
| @@ -1363,6 +1363,7 @@ more sections in stripped file than debug file -- arguments reversed?")); |
| /* Match each debuginfo section with its corresponding stripped section. */ |
| bool check_prelink = false; |
| Elf_Scn *unstripped_symtab = NULL; |
| + size_t unstripped_strndx = 0; |
| size_t alloc_avail = 0; |
| scn = NULL; |
| while ((scn = elf_nextscn (unstripped, scn)) != NULL) |
| @@ -1374,11 +1375,12 @@ more sections in stripped file than debug file -- arguments reversed?")); |
| if (shdr->sh_type == SHT_SYMTAB) |
| { |
| unstripped_symtab = scn; |
| + unstripped_strndx = shdr->sh_link; |
| continue; |
| } |
| |
| const size_t ndx = elf_ndxscn (scn); |
| - if (ndx == unstripped_shstrndx) |
| + if (ndx == unstripped_shstrndx || ndx == unstripped_strndx) |
| continue; |
| |
| const char *name = get_section_name (ndx, shdr, shstrtab); |
| @@ -1485,13 +1487,11 @@ more sections in stripped file than debug file -- arguments reversed?")); |
| } |
| |
| if (unstripped_symtab != NULL && stripped_symtab != NULL |
| - && secndx == stripped_symtab->shdr.sh_link) |
| + && secndx == stripped_symtab->shdr.sh_link |
| + && unstripped_strndx != 0) |
| { |
| /* ... nor its string table. */ |
| - GElf_Shdr shdr_mem; |
| - GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); |
| - ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); |
| - ndx_section[secndx - 1] = shdr->sh_link; |
| + ndx_section[secndx - 1] = unstripped_strndx; |
| continue; |
| } |
| |
| -- |
| 2.8.3 |
| |