[COMMITTED] libelf: Return error if elf_compress_gnu is used on SHF_COMPRESSED section.

2018-08-18 Thread Mark Wielaard
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.

2018-08-18 Thread Mark Wielaard
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.

2018-08-18 Thread Mark Wielaard
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.

2018-08-18 Thread Mark Wielaard
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

2018-08-18 Thread mark at klomp dot org
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.

2018-08-18 Thread mark at klomp dot org
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

2018-08-18 Thread mark at klomp dot org
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

2018-08-18 Thread mark at klomp dot org
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.