[Bug tools/21299] New: heap-based buffer overflow in handle_gnu_hash (readelf.c)

2017-03-24 Thread ago at gentoo dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21299

Bug ID: 21299
   Summary: heap-based buffer overflow in handle_gnu_hash
(readelf.c)
   Product: elfutils
   Version: unspecified
Status: UNCONFIRMED
  Severity: normal
  Priority: P2
 Component: tools
  Assignee: unassigned at sourceware dot org
  Reporter: ago at gentoo dot org
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 9936
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9936&action=edit
stacktrace

On elfutils-0.168:

# eu-readelf -a $FILE

READ of size 4 at 0x61109ffc thread T0
#0 0x421a8b in handle_gnu_hash
/tmp/portage/dev-libs/elfutils-0.168/work/elfutils-0.168/src/readelf.c:3268

Compiled with: gcc-6.3.0

Reproducer:
https://github.com/asarubbo/poc/blob/master/00225-elfutils-heapoverflow-handle_gnu_hash

Stacktrace attached.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug tools/21300] New: heap-based buffer overflow in ebl_object_note_type_name (eblobjnotetypename.c)

2017-03-24 Thread ago at gentoo dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21300

Bug ID: 21300
   Summary: heap-based buffer overflow in
ebl_object_note_type_name (eblobjnotetypename.c)
   Product: elfutils
   Version: unspecified
Status: UNCONFIRMED
  Severity: normal
  Priority: P2
 Component: tools
  Assignee: unassigned at sourceware dot org
  Reporter: ago at gentoo dot org
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 9937
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9937&action=edit
stacktrace

On elfutils-0.168:

# eu-readelf -a $FILE
READ of size 1 at 0x6020ef9c thread T0
#1 0x4f63a7 in ebl_object_note_type_name
/tmp/portage/dev-libs/elfutils-0.168/work/elfutils-0.168/libebl/eblobjnotetypename.c:48

Compiled with: gcc-6.3.0

Reproducer:
https://github.com/asarubbo/poc/blob/master/00226-elfutils-heapoverflow-ebl_object_note_type_name

Stacktrace attached.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libelf/21301] New: memory allocation failure in __libelf_decompress

2017-03-24 Thread ago at gentoo dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21301

Bug ID: 21301
   Summary: memory allocation failure in __libelf_decompress
   Product: elfutils
   Version: unspecified
Status: UNCONFIRMED
  Severity: normal
  Priority: P2
 Component: libelf
  Assignee: unassigned at sourceware dot org
  Reporter: ago at gentoo dot org
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 9938
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9938&action=edit
stacktrace

AN IMPORTANT NOTE:
as the stacktrace said this can be a false positive, so if you think that there
isn't anything to fix, feel free to close.

On elfutils-0.168:

# eu-readelf -a $FILE
==1927==WARNING: AddressSanitizer failed to allocate 0x280065041580 bytes
#5 0x7f85fb88dd1e in __libelf_decompress
/tmp/portage/dev-libs/elfutils-0.168/work/elfutils-0.168/libelf/elf_compress.c:214


Compiled with: gcc-6.3.0

Reproducer:
https://github.com/asarubbo/poc/blob/master/00227-elfutils-memallocfailure

Stacktrace attached.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug tools/21299] heap-based buffer overflow in handle_gnu_hash (readelf.c)

2017-03-24 Thread mjw at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21299

Mark Wielaard  changed:

   What|Removed |Added

 CC||mjw at redhat dot com

--- Comment #1 from Mark Wielaard  ---
Thanks, it was an off-by-one sanity check.

diff --git a/src/readelf.c b/src/readelf.c
index 8d96ba3..490b6d5 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3263,7 +3263,7 @@ handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, 
++nsyms;
if (maxlength < ++lengths[cnt])
  ++maxlength;
-   if (inner > max_nsyms)
+   if (inner >= max_nsyms)
  goto invalid_data;
  }
while ((chain[inner++] & 1) == 0);

max_nsyms is the maximum number, but inner is a zero-based index.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH] readelf: Fix off by one sanity check in handle_gnu_hash.

2017-03-24 Thread Mark Wielaard
We sanity check to make sure we don't index outside the chain array
by testing inner > max_nsyms. But inner is a zero-based index, while
max_nsyms is the maximum number. Change the check to inner >= max_nsyms.

https://sourceware.org/bugzilla/show_bug.cgi?id=21299

Signed-off-by: Mark Wielaard 
---
 src/ChangeLog | 5 +
 src/readelf.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 0601198..9dd76c0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-24  Mark Wielaard  
+
+   * readelf.c (handle_gnu_hash): Check inner < max_nsyms before
+   indexing into chain array.
+
 2017-02-16  Ulf Hermann  
 
* addr2line.c: Include printversion.h
diff --git a/src/readelf.c b/src/readelf.c
index 8d96ba3..490b6d5 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3263,7 +3263,7 @@ handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, 
size_t shstrndx)
++nsyms;
if (maxlength < ++lengths[cnt])
  ++maxlength;
-   if (inner > max_nsyms)
+   if (inner >= max_nsyms)
  goto invalid_data;
  }
while ((chain[inner++] & 1) == 0);
-- 
1.8.3.1



[Bug tools/21300] heap-based buffer overflow in ebl_object_note_type_name (eblobjnotetypename.c)

2017-03-24 Thread mjw at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21300

Mark Wielaard  changed:

   What|Removed |Added

 CC||mjw at redhat dot com

--- Comment #1 from Mark Wielaard  ---
Nice find. The issue is with notes that have a zero sized name (and also no
descriptor data at the end of a note section).

"The system reserves note information with no name (namesz==0) and with a
zero-length name (name[0]=='\0') but currently defines no types. All other
names must have at least one non-null character."

So we must explicitly check for namesz == 0 before using the name data in the
note.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH] Use the empty string for note names with zero size (without any data).

2017-03-24 Thread Mark Wielaard
ELF notes can have a zero sized name. In which case there is no data at
all (so also no zero terminator). Make sure to use the empty string for
such notes if the code does not otherwise explicitly check n_namesz.

https://sourceware.org/bugzilla/show_bug.cgi?id=21300

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog   | 6 ++
 libdwfl/linux-core-attach.c | 9 ++---
 src/ChangeLog   | 6 ++
 src/elfcmp.c| 6 --
 src/readelf.c   | 2 +-
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 4c9f4f6..ede6d47 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2017-03-24  Mark Wielaard  
+
+   * linux-core-attach.c (core_next_thread): If n_namesz == 0 then
+   the note name data is the empty string.
+   (dwfl_core_file_attach): Likewise.
+
 2017-02-15  Ulf Hermann  
 
* linux-kernel-modules.c: Include system.h.
diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
index 93d0e46..f82ed03 100644
--- a/libdwfl/linux-core-attach.c
+++ b/libdwfl/linux-core-attach.c
@@ -125,7 +125,8 @@ core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void 
*dwfl_arg,
  &desc_offset)) > 0)
 {
   /* Do not check NAME for now, help broken Linux kernels.  */
-  const char *name = note_data->d_buf + name_offset;
+  const char *name = (nhdr.n_namesz == 0
+ ? "" : note_data->d_buf + name_offset);
   const char *desc = note_data->d_buf + desc_offset;
   GElf_Word regs_offset;
   size_t nregloc;
@@ -178,7 +179,8 @@ core_set_initial_registers (Dwfl_Thread *thread, void 
*thread_arg_voidp)
   /* __libdwfl_attach_state_for_core already verified the note is there.  */
   assert (getnote_err != 0);
   /* Do not check NAME for now, help broken Linux kernels.  */
-  const char *name = note_data->d_buf + name_offset;
+  const char *name = (nhdr.n_namesz == 0
+ ? "" : note_data->d_buf + name_offset);
   const char *desc = note_data->d_buf + desc_offset;
   GElf_Word regs_offset;
   size_t nregloc;
@@ -367,7 +369,8 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
&nhdr, &name_offset, &desc_offset)) > 0)
 {
   /* Do not check NAME for now, help broken Linux kernels.  */
-  const char *name = note_data->d_buf + name_offset;
+  const char *name = (nhdr.n_namesz == 0
+ ? "" : note_data->d_buf + name_offset);
   const char *desc = note_data->d_buf + desc_offset;
   GElf_Word regs_offset;
   size_t nregloc;
diff --git a/src/ChangeLog b/src/ChangeLog
index 9dd76c0..41381aa 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,11 @@
 2017-03-24  Mark Wielaard  
 
+   * elfcmp.c (main): If n_namesz == 0 then the note name data is the
+   empty string.
+   * readelf.c (handle_notes_data): Likewise.
+
+2017-03-24  Mark Wielaard  
+
* readelf.c (handle_gnu_hash): Check inner < max_nsyms before
indexing into chain array.
 
diff --git a/src/elfcmp.c b/src/elfcmp.c
index 7673cf2..5046420 100644
--- a/src/elfcmp.c
+++ b/src/elfcmp.c
@@ -419,7 +419,8 @@ main (int argc, char *argv[])
   && (off1 = gelf_getnote (data1, off1, ¬e1,
&name_offset, &desc_offset)) > 0)
  {
-   const char *name1 = data1->d_buf + name_offset;
+   const char *name1 = (note1.n_namesz == 0
+? "" : data1->d_buf + name_offset);
const void *desc1 = data1->d_buf + desc_offset;
if (off2 >= data2->d_size)
  {
@@ -435,7 +436,8 @@ main (int argc, char *argv[])
  error (2, 0, gettext ("\
 cannot read note section [%zu] '%s' in '%s': %s"),
 elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1));
-   const char *name2 = data2->d_buf + name_offset;
+   const char *name2 = (note2.n_namesz == 0
+? "" : data2->d_buf + name_offset);
const void *desc2 = data2->d_buf + desc_offset;
 
if (note1.n_namesz != note2.n_namesz
diff --git a/src/readelf.c b/src/readelf.c
index 490b6d5..97a43b0 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -9365,7 +9365,7 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
 && (offset = gelf_getnote (data, offset,
&nhdr, &name_offset, &desc_offset)) > 0)
 {
-  const char *name = data->d_buf + name_offset;
+  const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
   const char *desc = data->d_buf + desc_offset;
 
   char buf[100];
-- 
1.8.3.1



[Bug tools/21300] heap-based buffer overflow in ebl_object_note_type_name (eblobjnotetypename.c)

2017-03-24 Thread mjw at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21300

--- Comment #2 from Mark Wielaard  ---
Posted a patch:
https://sourceware.org/ml/elfutils-devel/2017-q1/msg00111.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libelf/21301] memory allocation failure in __libelf_decompress

2017-03-24 Thread mjw at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21301

Mark Wielaard  changed:

   What|Removed |Added

 CC||mjw at redhat dot com

--- Comment #1 from Mark Wielaard  ---
That is slightly tricky. We do have to trust the input data to give us the
expected output size. We won't know if that was correct till we decompressed
the input. We do actually double check the given output size was correct at the
end of the decompression. But we could catch some really bogus sizes before
trying to allocate a giant amount of memory and decompressing stuff for nothing
(like in this case).

diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index dac0ac6..711be59 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -211,6 +211,15 @@ void *
 internal_function
 __libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
 {
+  /* Catch highly unlikely compression ratios so we don't allocate
+ some giant amount of memory for nothing. The max compression
+ factor 1032:1 comes from http://www.zlib.net/zlib_tech.html  */
+  if (unlikely (size_out / 1032 > size_in))
+{
+  __libelf_seterrno (ELF_E_INVALID_DATA);
+  return NULL;
+}
+
   void *buf_out = malloc (size_out);
   if (unlikely (buf_out == NULL))
 {

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH] libelf: Check compression ratio before trying to allocate output buffer.

2017-03-24 Thread Mark Wielaard
The maximum compression factor (http://www.zlib.net/zlib_tech.html) is
1032:1. Add a sanity check for that before trying to allocate lots of
memory and trying to decompress lots of bogus data.

https://sourceware.org/bugzilla/show_bug.cgi?id=21301

Signed-off-by: Mark Wielaard 
---
 libelf/ChangeLog  | 5 +
 libelf/elf_compress.c | 9 +
 2 files changed, 14 insertions(+)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 8539cb5..35e5271 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-24  Mark Wielaard  
+
+   * elf_compress.c (__libelf_decompress): Check insane compression
+   ratios before trying to allocate output buffer.
+
 2016-10-11  Akihiko Odaki  
Mark Wielaard  
 
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index dac0ac6..711be59 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -211,6 +211,15 @@ void *
 internal_function
 __libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
 {
+  /* Catch highly unlikely compression ratios so we don't allocate
+ some giant amount of memory for nothing. The max compression
+ factor 1032:1 comes from http://www.zlib.net/zlib_tech.html  */
+  if (unlikely (size_out / 1032 > size_in))
+{
+  __libelf_seterrno (ELF_E_INVALID_DATA);
+  return NULL;
+}
+
   void *buf_out = malloc (size_out);
   if (unlikely (buf_out == NULL))
 {
-- 
1.8.3.1



Re: [PATCH] backends: Add support for EM_PPC64 GNU_ATTRIBUTES.

2017-03-24 Thread Mark Wielaard
On Wed, 2017-02-15 at 14:39 +0100, Mark Wielaard wrote:
> ppc64 and ppc64le ELF files can also contain a power specific
> .gnu.attributes section. Add support for those and recognize the new
> GNU_Power_ABI_FP Single-precision hard float value.

I pushed this to master.
It has been in the fedora elfutils for some time now.


Re: [PATCH] libasm: Fix GCC7 one -Wformat-truncation=2 warning.

2017-03-24 Thread Mark Wielaard
On Sun, 2017-02-12 at 21:54 +0100, Mark Wielaard wrote:
> Make sure that if we have really many labels the tempsym doesn't get
> truncated because it is too small to hold the whole name.

I pushed this to master.
It has been in the fedora elfutils for some time now.

> This doesn't enable -Wformat-truncation=2 or fix other "issues" pointed
> out by enabling this warning because there are currently some issues
> with it. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79448

The above bug has been resolved. Plus some others with this warning.
But I haven't finished the work to enable this warning by default yet.

Cheers,

Mark