elfutils 0.174

This commit is contained in:
Mark Wielaard 2018-09-14 14:33:46 +02:00
parent fe9cd06e65
commit 7a679f4677
6 changed files with 17 additions and 316 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@
/elfutils-0.171.tar.bz2
/elfutils-0.172.tar.bz2
/elfutils-0.173.tar.bz2
/elfutils-0.174.tar.bz2

View File

@ -1,63 +0,0 @@
commit 73e83285fbeac648edb60a0c4767fad9d470cf0a
Author: Mark Wielaard <mark@klomp.org>
Date: Sat Jul 21 23:40:11 2018 +0200
unstrip: Handle SHT_GROUP sections in ET_REL files.
SHT_GROUP sections are put in both the stripped and debug file.
Handle correcting the symbol table/name entry of the group only once.
The testfile was generated with the gcc annobin plugin.
Signed-off-by: Mark Wielaard <mark@klomp.org>
diff --git a/src/unstrip.c b/src/unstrip.c
index 057efef..cb1f7dc 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -563,7 +563,11 @@ adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr,
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
- if (shdr->sh_type != SHT_NOBITS && shdr->sh_link == new_sh_link)
+ /* Don't redo SHT_GROUP, groups are in both the stripped and debug,
+ it will already have been done by adjust_relocs for the
+ stripped_symtab. */
+ if (shdr->sh_type != SHT_NOBITS && shdr->sh_type != SHT_GROUP
+ && shdr->sh_link == new_sh_link)
adjust_relocs (scn, scn, shdr, map, symshdr);
}
}
commit 47092416243d54e4cff3cd2558ece8b93695d54e
Author: Mark Wielaard <mark@klomp.org>
Date: Tue Jul 24 23:34:19 2018 +0200
unstrip: Also check sh_size in compare_unalloc_sections.
compare_unalloc_sections only checked sh_flags and the section names.
This would cause stripped/debug section mismatches when there were
multiple sections with the same name and flags. Fix this by also checking
the size of the section matches.
Add a testcase that has two ".group" sections created on i386 with the
gcc annobin plugin.
Signed-off-by: Mark Wielaard <mark@klomp.org>
diff --git a/src/unstrip.c b/src/unstrip.c
index cb1f7dc..ec46c95 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -709,6 +709,12 @@ compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
if (shdr1->sh_flags > shdr2->sh_flags)
return 1;
+ /* Sizes should be the same. */
+ if (shdr1->sh_size < shdr2->sh_size)
+ return -1;
+ if (shdr1->sh_size > shdr2->sh_size)
+ return 1;
+
/* Sort by name as last resort. */
return strcmp (name1, name2);
}

View File

@ -1,136 +0,0 @@
commit 47499e57d9321f4e45f33a3c1ab12264510ee7a4
Author: Mark Wielaard <mark@klomp.org>
Date: Sat Jul 21 16:10:25 2018 +0200
elfcompress: Swap fchmod and fchown calls on new file.
Calling fchmod with a suid bit on a file might silently fail or the suid
bit might be slilently cleared by a call to fchown if already set. Swap
the calls so that the owner is set first and then set the suid bit.
https://bugzilla.redhat.com/show_bug.cgi?id=1607044
Signed-off-by: Mark Wielaard <mark@klomp.org>
diff --git a/src/elfcompress.c b/src/elfcompress.c
index bdb0e3b..1a0f984 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -1235,13 +1235,16 @@ process_file (const char *fname)
elf_end (elfnew);
elfnew = NULL;
- /* Try to match mode and owner.group of the original file. */
- if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
- if (verbose >= 0)
- error (0, errno, "Couldn't fchmod %s", fnew);
+ /* Try to match mode and owner.group of the original file.
+ Note to set suid bits we have to make sure the owner is setup
+ correctly first. Otherwise fchmod will drop them silently
+ or fchown may clear them. */
if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
if (verbose >= 0)
error (0, errno, "Couldn't fchown %s", fnew);
+ if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
+ if (verbose >= 0)
+ error (0, errno, "Couldn't fchmod %s", fnew);
/* Finally replace the old file with the new file. */
if (foutput == NULL)
commit d676c839e783996409d7845ea236e0883a827cbb
Author: Mark Wielaard <mark@klomp.org>
Date: Sat Jul 21 17:07:12 2018 +0200
elfcompress: Don't rewrite file if no section data needs to be updated.
If the input and output file are the same and no section needs to
be updated we really don't need to rewrite the file. Check whether
any matching section is already compressed or (GNU) decompressed.
Skip the section if it doesn't need to be changed. If no section data
needs updating end with success without rewriting/updating file.
With --force the file will still always be updated/rewritten even if
no section data needs to be (de)compressed.
Signed-off-by: Mark Wielaard <mark@klomp.org>
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 1a0f984..ae4708c 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -1,5 +1,5 @@
/* Compress or decompress an ELF file.
- Copyright (C) 2015, 2016 Red Hat, Inc.
+ Copyright (C) 2015, 2016, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -286,6 +286,15 @@ process_file (const char *fname)
return (sections[ndx / WORD_BITS] & (1U << (ndx % WORD_BITS))) != 0;
}
+ /* How many sections are we going to change? */
+ size_t get_sections (void)
+ {
+ size_t s = 0;
+ for (size_t i = 0; i < shnum / WORD_BITS + 1; i++)
+ s += __builtin_popcount (sections[i]);
+ return s;
+ }
+
int cleanup (int res)
{
elf_end (elf);
@@ -422,6 +431,9 @@ process_file (const char *fname)
names change and whether there is a symbol table that might need
to be adjusted be if the section header name table is changed.
+ If nothing needs changing, and the input and output file are the
+ same, we are done.
+
Second a collection pass that creates the Elf sections and copies
the data. This pass will compress/decompress section data when
needed. And it will collect all data needed if we'll need to
@@ -464,7 +476,26 @@ process_file (const char *fname)
if (section_name_matches (sname))
{
- if (shdr->sh_type != SHT_NOBITS
+ if (!force && type == T_DECOMPRESS
+ && (shdr->sh_flags & SHF_COMPRESSED) == 0
+ && strncmp (sname, ".zdebug", strlen (".zdebug")) != 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already decompressed\n", ndx, sname);
+ }
+ else if (!force && type == T_COMPRESS_ZLIB
+ && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already compressed\n", ndx, sname);
+ }
+ else if (!force && type == T_COMPRESS_GNU
+ && strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already GNU compressed\n", ndx, sname);
+ }
+ else if (shdr->sh_type != SHT_NOBITS
&& (shdr->sh_flags & SHF_ALLOC) == 0)
{
set_section (ndx);
@@ -518,6 +549,14 @@ process_file (const char *fname)
}
}
+ if (foutput == NULL && get_sections () == 0)
+ {
+ if (verbose > 0)
+ printf ("Nothing to do.\n");
+ fnew = NULL;
+ return cleanup (0);
+ }
+
if (adjust_names)
{
names = dwelf_strtab_init (true);

View File

@ -1,108 +0,0 @@
diff --git a/src/strip.c b/src/strip.c
index 791347c..1367de7 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -661,6 +661,11 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
}
+ /* Track whether allocated sections all come before non-allocated ones. */
+ bool seen_allocated = false;
+ bool seen_unallocated = false;
+ bool mixed_allocated_unallocated = false;
+
/* Prepare section information data structure. */
scn = NULL;
cnt = 1;
@@ -676,6 +681,17 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
INTERNAL_ERROR (fname);
+ /* Normally (in non-ET_REL files) we see all allocated sections first,
+ then all non-allocated. */
+ if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
+ seen_unallocated = true;
+ else
+ {
+ if (seen_unallocated && seen_allocated)
+ mixed_allocated_unallocated = true;
+ seen_allocated = true;
+ }
+
/* Get the name of the section. */
shdr_info[cnt].name = elf_strptr (elf, shstrndx,
shdr_info[cnt].shdr.sh_name);
@@ -1535,24 +1551,58 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
}
}
- /* If we have to, compute the offset of the section. */
- if (shdr_info[cnt].shdr.sh_offset == 0)
- shdr_info[cnt].shdr.sh_offset
- = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
- & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
-
- /* Set the section header in the new file. */
- if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
- /* There cannot be any overflows. */
- INTERNAL_ERROR (fname);
+ /* If we have to, compute the offset of the section.
+ If allocate and unallocated sections are mixed, we only update
+ the allocated ones now. The unallocated ones come second. */
+ if (! mixed_allocated_unallocated
+ || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
+ {
+ if (shdr_info[cnt].shdr.sh_offset == 0)
+ shdr_info[cnt].shdr.sh_offset
+ = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
+ & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
+
+ /* Set the section header in the new file. */
+ if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
+ /* There cannot be any overflows. */
+ INTERNAL_ERROR (fname);
- /* Remember the last section written so far. */
- GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
- ? shdr_info[cnt].shdr.sh_size : 0);
- if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
- lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
+ /* Remember the last section written so far. */
+ GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
+ ? shdr_info[cnt].shdr.sh_size : 0);
+ if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
+ lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
+ }
}
+ /* We might have to update the unallocated sections after we done the
+ allocated ones. lastoffset is set to right after the last allocated
+ section. */
+ if (mixed_allocated_unallocated)
+ for (cnt = 1; cnt <= shdridx; ++cnt)
+ if (shdr_info[cnt].idx > 0)
+ {
+ scn = elf_getscn (newelf, shdr_info[cnt].idx);
+ if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
+ {
+ if (shdr_info[cnt].shdr.sh_offset == 0)
+ shdr_info[cnt].shdr.sh_offset
+ = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
+ & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
+
+ /* Set the section header in the new file. */
+ if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
+ /* There cannot be any overflows. */
+ INTERNAL_ERROR (fname);
+
+ /* Remember the last section written so far. */
+ GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
+ ? shdr_info[cnt].shdr.sh_size : 0);
+ if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
+ lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
+ }
+ }
+
/* Adjust symbol references if symbol tables changed. */
if (any_symtab_changes)
/* Find all relocation sections which use this symbol table. */

View File

@ -1,7 +1,7 @@
Name: elfutils
Summary: A collection of utilities and DSOs to handle ELF files and DWARF data
Version: 0.173
%global baserelease 8
Version: 0.174
%global baserelease 1
URL: http://elfutils.org/
%global source_url ftp://sourceware.org/pub/elfutils/%{version}/
License: GPLv3+ and (GPLv2+ or LGPLv3+)
@ -21,9 +21,6 @@ Source: %{?source_url}%{name}-%{version}.tar.bz2
# Patches
Patch1: elfutils-0.173-new-notes-hack.patch
Patch2: elfutils-0.173-elfcompress.patch
Patch3: elfutils-0.173-annobingroup.patch
Patch4: elfutils-0.173-strip-alloc-nonalloc.patch
Requires: elfutils-libelf%{depsuffix} = %{version}-%{release}
Requires: elfutils-libs%{depsuffix} = %{version}-%{release}
@ -193,9 +190,6 @@ profiling) of processes.
# Apply patches
%patch1 -p1 -b .notes_hack
%patch2 -p1 -b .elfcompress
%patch3 -p1 -b .annobingroup
%patch4 -p1 -b .strip-alloc-nonalloc
# In case the above patches added any new test scripts, make sure they
# are executable.
@ -328,6 +322,19 @@ fi
%endif
%changelog
* Fri Sep 14 2018 Mark Wielaard <mjw@fedoraproject.org> - 0.174-1
- New upstream release
- libelf, libdw and all tools now handle extended shnum and shstrndx
correctly (#1608390).
- elfcompress: Don't rewrite input file if no section data needs
updating. Try harder to keep same file mode bits (suid) on rewrite.
- strip: Handle mixed (out of order) allocated/non-allocated sections.
- unstrip: Handle SHT_GROUP sections.
- backends: RISCV and M68K now have backend implementations to
generate CFI based backtraces.
- Fixes CVE-2018-16062, CVE-2018-16402 and CVE-2018-16403
(#1623753, #1625051, #1625056).
* Tue Jul 31 2018 Florian Weimer <fweimer@redhat.com> - 0.173-8
- Rebuild with fixed binutils

View File

@ -1 +1 @@
SHA512 (elfutils-0.173.tar.bz2) = 7f38e4ce2098b685f15030bf01f0a66a74aa32fbfcead0304c1d0e0a929b348a72f99e685cd4605465f4337393382112f64b8847e6c2f7cc1a57a4fd03d03eb3
SHA512 (elfutils-0.174.tar.bz2) = 696708309c2a9a076099748809ecdc0490f4a8a842b2efc1aae0d746e7c5a8b203743f5626739eff837216b0c052696516b2821f5d3cc3f2eef86597c96d42df