[COMMITTED] libelf: Return error if elf_compress_gnu is used on SHF_COMPRESSED section.
Compressing a section that is already compressed is fine, but useless. But it isn't possible to gnu compress (or decompress) a SHF_COMPRESSED section since there is no state kept that would tell if the section was first GNU compressed or first gabi compressed. Calling elf_compress_gnu on a section and then calling elf_compress on it to decompress it twice could cause a crash (the other way around is fine). Just disallow it. https://sourceware.org/bugzilla/show_bug.cgi?id=23528 Signed-off-by: Mark Wielaard --- libelf/ChangeLog | 7 +++ libelf/elf_compress_gnu.c | 4 +++- libelf/libelf.h | 5 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 744c5b4d..7c884b00 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,10 @@ +2018-08-18 Mark Wielaard + + * libelf.h (elf_compress_gnu): Add documentation about + interaction between SHF_COMPRESED and elf_compress_gnu. + * elf_compress_gnu.c (elf_compress_gnu): Return error if section + sh_flags has SHF_COMPRESSED set. + 2018-07-27 Mark Wielaard * libelf.h (elf_getshdrstrndx): Fix documentation. diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c index c35dc395..dfa7c571 100644 --- a/libelf/elf_compress_gnu.c +++ b/libelf/elf_compress_gnu.c @@ -80,7 +80,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) sh_addralign = shdr->sh_addralign; } - if ((sh_flags & SHF_ALLOC) != 0) + /* Allocated sections, or sections that are already are compressed + cannot (also) be GNU compressed. */ + if ((sh_flags & SHF_ALLOC) != 0 || (sh_flags & SHF_COMPRESSED)) { __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); return -1; diff --git a/libelf/libelf.h b/libelf/libelf.h index 61f19231..d11358cc 100644 --- a/libelf/libelf.h +++ b/libelf/libelf.h @@ -366,6 +366,11 @@ extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn); It is an error to request compression for a section that already has SHF_COMPRESSED set, or (for elf_compress) to request decompression for an section that doesn't have SHF_COMPRESSED set. + If a section has SHF_COMPRESSED set then calling elf_compress_gnu + will result in an error. The section has to be decompressed first + using elf_compress. Calling elf_compress on a section compressed + with elf_compress_gnu is fine, but probably useless. + It is always an error to call these functions on SHT_NOBITS sections or if the section has the SHF_ALLOC flag set. elf_compress_gnu will not check whether the section name starts -- 2.18.0
[COMMITTED] libdw, readelf: Make sure there is enough data to read full aranges header.
dwarf_getaranges didn't check if there was enough data left to read both the address and segment size. readelf didn't check there was enough data left to read the segment size. https://sourceware.org/bugzilla/show_bug.cgi?id=23541 Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 5 + libdw/dwarf_getaranges.c | 4 src/ChangeLog| 5 + src/readelf.c| 2 ++ 4 files changed, 16 insertions(+) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index cb4f34ed..472d9228 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2018-08-18 Mark Wielaard + + * dwarf_getaranges.c (dwarf_getaranges.c): Make sure there is enough + data to read the address and segment size. + 2018-07-04 Ross Burton * libdw_alloc.c: Remove error.h include. diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c index bff9c860..de5b81ba 100644 --- a/libdw/dwarf_getaranges.c +++ b/libdw/dwarf_getaranges.c @@ -148,6 +148,10 @@ dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges) length_bytes, &offset, IDX_debug_info, 4)) goto fail; + /* Next up two bytes for address and segment size. */ + if (readp + 2 > readendp) + goto invalid; + unsigned int address_size = *readp++; if (unlikely (address_size != 4 && address_size != 8)) goto invalid; diff --git a/src/ChangeLog b/src/ChangeLog index 8c89f83d..2f9f7747 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-08-18 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Make sure there is enough + data to read the header segment size. + 2018-08-18 Mark Wielaard * elflint.c (check_sysv_hash): Calculate needed size using unsigned diff --git a/src/readelf.c b/src/readelf.c index 7b5707f8..7b488ac5 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -5447,6 +5447,8 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)), goto next_table; } + if (readp + 1 > readendp) + goto invalid_data; unsigned int segment_size = *readp++; printf (gettext (" Segment size: %6" PRIu64 "\n\n"), (uint64_t) segment_size); -- 2.18.0
[COMMITTED] libdw: Check end of attributes list consistently.
dwarf_child (__libdw_find_attr), dwarf_getabbrevattr[_data] and dwarf_getattrs all assume the end of the attribute list is when both the name (code) and form of the attribute are zero. dwarf_getabbrev (__libdw_getabbrev) and dwarf_hasattr assume the end of the attribute list is when either the name (code) or the form of the attribute is zero. The DWARF spec says: "The series of attribute specifications ends with an entry containing 0 for the name and 0 for the form." So the first check is correct. Make sure dwarf_getabbrev and dwarf_hasattr use the same check. This is important since all other functions expect dwarf_getabbrev (__libdw_getabbrev) to have done a data sanity check of the attribute. So if the ending condition is different it could cause a crash. https://sourceware.org/bugzilla/show_bug.cgi?id=23529 Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 7 +++ libdw/dwarf_getabbrev.c | 2 +- libdw/dwarf_hasattr.c | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 472d9228..7cb25923 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2018-08-18 Mark Wielaard + + * dwarf_getabbrev.c (__libdw_getabbrev): Continue until both name + and form are zero. + * dwarf_hasattr.c (dwarf_hasattr): Stop when both name and form + are zero. + 2018-08-18 Mark Wielaard * dwarf_getaranges.c (dwarf_getaranges.c): Make sure there is enough diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c index 988d12c2..6a7e981b 100644 --- a/libdw/dwarf_getabbrev.c +++ b/libdw/dwarf_getabbrev.c @@ -140,7 +140,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, get_sleb128 (formval, abbrevp, end); } } - while (attrname != 0 && attrform != 0); + while (attrname != 0 || attrform != 0); /* Return the length to the caller if she asked for it. */ if (lengthp != NULL) diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c index 90053b13..eca08394 100644 --- a/libdw/dwarf_hasattr.c +++ b/libdw/dwarf_hasattr.c @@ -60,8 +60,8 @@ dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) unsigned int attr_form; get_uleb128_unchecked (attr_form, attrp); - /* We can stop if we found the attribute with value zero. */ - if (attr_name == 0 || attr_form == 0) + /* We can stop if we found the end of the attribute list. */ + if (attr_name == 0 && attr_form == 0) return 0; if (attr_name == search_name) -- 2.18.0
[COMMITTED] elflint: Fix check_sysv_hash[64] sanity checks to not overflow.
The sanity checks for how many words were needed in the section could overflow causing errors. Fix the checks. https://sourceware.org/bugzilla/show_bug.cgi?id=23542 Signed-off-by: Mark Wielaard --- src/ChangeLog | 7 +++ src/elflint.c | 7 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a01bd756..8c89f83d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2018-08-18 Mark Wielaard + + * elflint.c (check_sysv_hash): Calculate needed size using unsigned + long long int to prevent overflow. + (check_sysv_hash64): Calculate maxwords used separately before + comparison to prevent overflow. + 2018-07-24 Mark Wielaard * unstrip.c (compare_unalloc_sections): Also compare sh_size. diff --git a/src/elflint.c b/src/elflint.c index eec799b2..90e8fed4 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -2023,7 +2023,7 @@ check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; - if (shdr->sh_size < (2 + nbucket + nchain) * sizeof (Elf32_Word)) + if (shdr->sh_size < (2ULL + nbucket + nchain) * sizeof (Elf32_Word)) { ERROR (gettext ("\ section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), @@ -2077,7 +2077,10 @@ check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; - if (shdr->sh_size < (2 + nbucket + nchain) * sizeof (Elf64_Xword)) + uint64_t maxwords = shdr->sh_size / sizeof (Elf64_Xword); + if (maxwords < 2 + || maxwords - 2 < nbucket + || maxwords - 2 - nbucket < nchain) { ERROR (gettext ("\ section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), -- 2.18.0
[Bug general/23542] heap-buffer-overflow in /elfutils/src/elflint.c:2055 check_sysv_hash
https://sourceware.org/bugzilla/show_bug.cgi?id=23542 Mark Wielaard changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #2 from Mark Wielaard --- commit c9f90a70900e753dde15cc9348dcf7de08b031eb Author: Mark Wielaard Date: Sat Aug 18 13:17:45 2018 +0200 elflint: Fix check_sysv_hash[64] sanity checks to not overflow. The sanity checks for how many words were needed in the section could overflow causing errors. Fix the checks. https://sourceware.org/bugzilla/show_bug.cgi?id=23542 Signed-off-by: Mark Wielaard -- You are receiving this mail because: You are on the CC list for the bug.
[Bug libelf/23528] When executing ./eu-nm or ./eu-readelf -aAdehIlnrsSVcp -w, AddressSanitizer catch a double-free crash.
https://sourceware.org/bugzilla/show_bug.cgi?id=23528 Mark Wielaard changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #4 from Mark Wielaard --- commit 56b18521fb8d46d40fc090c0de9d11a08bc982fa Author: Mark Wielaard Date: Sat Aug 18 12:42:16 2018 +0200 libelf: Return error if elf_compress_gnu is used on SHF_COMPRESSED section. Compressing a section that is already compressed is fine, but useless. But it isn't possible to gnu compress (or decompress) a SHF_COMPRESSED section since there is no state kept that would tell if the section was first GNU compressed or first gabi compressed. Calling elf_compress_gnu on a section and then calling elf_compress on it to decompress it twice could cause a crash (the other way around is fine). Just disallow it. https://sourceware.org/bugzilla/show_bug.cgi?id=23528 Signed-off-by: Mark Wielaard -- You are receiving this mail because: You are on the CC list for the bug.
[Bug libdw/23541] heap-buffer-overflow in /elfutils/libdw/dwarf_getaranges.c:156
https://sourceware.org/bugzilla/show_bug.cgi?id=23541 Mark Wielaard changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #2 from Mark Wielaard --- commit 29e31978ba51c1051743a503ee325b5ebc03d7e9 Author: Mark Wielaard Date: Sat Aug 18 13:27:48 2018 +0200 libdw, readelf: Make sure there is enough data to read full aranges header. dwarf_getaranges didn't check if there was enough data left to read both the address and segment size. readelf didn't check there was enough data left to read the segment size. https://sourceware.org/bugzilla/show_bug.cgi?id=23541 Signed-off-by: Mark Wielaard -- You are receiving this mail because: You are on the CC list for the bug.
[Bug backends/23529] heap-buffer-overflow in eu-readelf
https://sourceware.org/bugzilla/show_bug.cgi?id=23529 Mark Wielaard changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #2 from Mark Wielaard --- commit 6983e59b727458a6c64d9659c85f08218bc4fcda Author: Mark Wielaard Date: Sat Aug 18 19:51:27 2018 +0200 libdw: Check end of attributes list consistently. dwarf_child (__libdw_find_attr), dwarf_getabbrevattr[_data] and dwarf_getattrs all assume the end of the attribute list is when both the name (code) and form of the attribute are zero. dwarf_getabbrev (__libdw_getabbrev) and dwarf_hasattr assume the end of the attribute list is when either the name (code) or the form of the attribute is zero. The DWARF spec says: "The series of attribute specifications ends with an entry containing 0 for the name and 0 for the form." So the first check is correct. Make sure dwarf_getabbrev and dwarf_hasattr use the same check. This is important since all other functions expect dwarf_getabbrev (__libdw_getabbrev) to have done a data sanity check of the attribute. So if the ending condition is different it could cause a crash. https://sourceware.org/bugzilla/show_bug.cgi?id=23529 Signed-off-by: Mark Wielaard -- You are receiving this mail because: You are on the CC list for the bug.