strip: Don't remove real symbols from allocated symbol tables.

Having a symbol in an allocated symbol table (like .dynsym) that
points to an unallocated section is wrong. Traditionally strip
has removed such symbols if they are section or group symbols.
But removing a real symbol from an allocate symbol table is hard
and probably a mistake. Really removing it means rewriting the
dynamic segment and hash sections. Since we don't do that, don't
remove the symbol (and corrupt the ELF file). Do warn and set
the symbol section to SHN_UNDEF.

https://bugzilla.redhat.com/show_bug.cgi?id=1380961

Signed-off-by: Mark Wielaard <mjw@redhat.com>
This commit is contained in:
Mark Wielaard
2016-10-06 16:06:32 +02:00
parent 4f7b5ba962
commit 7bf4b63a49
2 changed files with 29 additions and 11 deletions
+5
View File
@@ -1,3 +1,8 @@
2016-10-06 Mark Wielaard <mjw@redhat.com>
* strip.c (handle_elf): Don't remove real symbols from allocated
symbol tables.
2016-08-25 Mark Wielaard <mjw@redhat.com>
* strip.c (handle_elf): Recompress with ELF_CHF_FORCE.
+24 -11
View File
@@ -1341,15 +1341,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Get the full section index, if necessary from the
XINDEX table. */
if (sym->st_shndx != SHN_XINDEX)
sec = shdr_info[sym->st_shndx].idx;
else
{
elf_assert (shndxdata != NULL
&& shndxdata->d_buf != NULL);
sec = shdr_info[xshndx].idx;
}
if (sym->st_shndx == SHN_XINDEX)
elf_assert (shndxdata != NULL
&& shndxdata->d_buf != NULL);
size_t sidx = (sym->st_shndx != SHN_XINDEX
? sym->st_shndx : xshndx);
sec = shdr_info[sidx].idx;
if (sec != 0)
{
@@ -1387,6 +1384,24 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
shdr_info[cnt].shdr.sh_info = destidx - 1;
}
}
else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0
&& GELF_ST_TYPE (sym->st_info) != STT_SECTION
&& shdr_info[sidx].shdr.sh_type != SHT_GROUP)
{
/* Removing a real symbol from an allocated
symbol table is hard and probably a
mistake. Really removing it means
rewriting the dynamic segment and hash
sections. Just warn and set the symbol
section to UNDEF. */
error (0, 0,
gettext ("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt);
sym->st_shndx = SHN_UNDEF;
if (gelf_update_sym (shdr_info[cnt].data, destidx,
sym) == 0)
INTERNAL_ERROR (fname);
shdr_info[cnt].newsymidx[inner] = destidx++;
}
else if (debug_fname != NULL
&& shdr_info[cnt].debug_data == NULL)
/* The symbol points to a section that is discarded
@@ -1394,8 +1409,6 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
this is a section or group signature symbol
for a section which has been removed. */
{
size_t sidx = (sym->st_shndx != SHN_XINDEX
? sym->st_shndx : xshndx);
elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
|| ((shdr_info[sidx].shdr.sh_type
== SHT_GROUP)