Re: [PATCH] libdwfl: Use process_vm_readv when available.

2018-03-28 Thread Mark Wielaard
On Tue, 2018-03-20 at 23:32 +0100, Mark Wielaard wrote:
> On Sun, Mar 18, 2018 at 01:43:23AM +0100, Mark Wielaard wrote:
> > If possible use process_vm_readv to read 4K blocks instead of fetching
> > each word individually with ptrace. For unwinding this often means we
> > only have to do one process_vm_readv of the stack instead of dozens of
> > ptrace calls. There is one 4K cache per process, cleared whenever a
> > thread is detached.
> 
> It seems to work well, but the GCC undefined sanitizer
> (configure --enable-sanitize-undefined) found an issue in the
> run-backtrace-native-biarch.sh testcase (from x86_64 to i686)
> when reading unaligned data. To fix that don't assign to the
> Dwarf_Word directly when unaligned, but use memcpy (which gcc
> seems to inline).

I pushed this to master now. Adding some comments about the word size
being actually architecture defined even though we use a 64bit
Dwarf_Word everywhere.

Cheers,

Mark


[Bug tools/23011] New: Infinite loop in handle_sysv_hash (src/readelf.c)

2018-03-28 Thread traceprobe at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=23011

Bug ID: 23011
   Summary: Infinite loop in handle_sysv_hash (src/readelf.c)
   Product: elfutils
   Version: unspecified
Status: UNCONFIRMED
  Severity: normal
  Priority: P2
 Component: tools
  Assignee: unassigned at sourceware dot org
  Reporter: traceprobe at gmail dot com
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 10920
  --> https://sourceware.org/bugzilla/attachment.cgi?id=10920&action=edit
poc for readelf

In elfutils version 0.170 and commit afffdff29228db03e2131af577f58a22aec6c1fe,
there is an infinite loop in handle_sysv_hash function of src/readelf.c, which
can be triggered by the POC below.

The issue happens since when processing System V-style hash table, the loop
value could be manipulated by input file. For instance in line 3150, if
chain[1] = 1, the program falls in infinite loop.

   3108 static void
   3109 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t
shstrndx)
   3110 {
   ...
   3141   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
   3142 {
   3143   Elf32_Word inner = bucket[cnt];
   3144   while (inner > 0 && inner < nchain)
   3145 {
   3146   ++nsyms;
   3147   if (maxlength < ++lengths[cnt])
   3148 ++maxlength;
   3149 
   3150   inner = chain[inner];
   3151 }
   3152 }

To reproduce the issue, run: ./eu-readelf -a $POC

The full stack trace is:

0x0040d78f in handle_sysv_hash (ebl=0x639670, scn=0x639238,
shdr=0x7fffdae0, shstrndx=256)
at /home/test/test/./elfutils/master/src/src/readelf.c:3144
3144  while (inner > 0 && inner < nchain)
(gdb) bt
#0  0x0040d78f in handle_sysv_hash (ebl=0x639670, scn=0x639238,
shdr=0x7fffdae0, shstrndx=256)
at /home/test/test/./elfutils/master/src/src/readelf.c:3144
#1  0x0040e24c in handle_hash (ebl=0x639670) at
/home/test/test/./elfutils/master/src/src/readelf.c:3360
#2  0x0040615d in process_elf_file (dwflmod=0x639340, fd=3) at
/home/test/test/./elfutils/master/src/src/readelf.c:915
#3  0x00405747 in process_dwflmod (dwflmod=0x639340, userdata=0x639350,
name=0x6394e0 "poc/id:00,src:000294,op:flip1,pos:51.", base=0,
arg=0x7fffdd50)
at /home/test/test/./elfutils/master/src/src/readelf.c:707
#4  0x77ba4c96 in dwfl_getmodules (dwfl=0x639000, callback=0x4056a9
, arg=0x7fffdd50, offset=0)
at /home/test/test/./elfutils/master/src/libdwfl/dwfl_getmodules.c:86
#5  0x00405c2d in process_file (fd=3, fname=0x7fffe2b9
"poc/id:00,src:000294,op:flip1,pos:51.", only_one=true)
at /home/test/test/./elfutils/master/src/src/readelf.c:806
#6  0x0040461e in main (argc=3, argv=0x7fffdf88) at
/home/test/test/./elfutils/master/src/src/readelf.c:322

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

[Bug tools/23011] Infinite loop in handle_sysv_hash (src/readelf.c)

2018-03-28 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=23011

Mark Wielaard  changed:

   What|Removed |Added

 CC||mark at klomp dot org

--- Comment #1 from Mark Wielaard  ---
ewww nasty. The idea is that the bucket entries point to the (first) symbol for
a particular hash. If that symbol is not the one needed then you look whether
there are other symbols with the same hash value in the chain. There are as
many chain entries as symbols, and for each symbol n, chain[n] is either zero
if there are no other symbols with the same hash, or it is the value of the
next symbol with the same hash (for the last one the chain entry is zero).
There are obviously not supposed to be "loops" in the chain. The easiest to
check would be the limit the number of chains to follow to the number of
symbols, which is equal the total number of chain entries (nchain).

Note that the same could happen in handle_sysv_hash64 which uses the same kind
of  bucket chain loop.

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

[Bug tools/23011] Infinite loop in handle_sysv_hash (src/readelf.c)

2018-03-28 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=23011

Mark Wielaard  changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2018-03-28
 Ever confirmed|0   |1

--- Comment #2 from Mark Wielaard  ---
Proposed fix: https://sourceware.org/ml/elfutils-devel/2018-q1/msg00118.html

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

[PATCH] readelf: Break sysv[64] symbol hash bucket chain loops.

2018-03-28 Thread Mark Wielaard
The bucket chain should not contain loops. If it does we should mark the
hash bucket chain as invalid. This is easily checked by noticing when we
have seen more than the number of chain elements. Which equals the max
number as symbols in the table.

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

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

diff --git a/src/ChangeLog b/src/ChangeLog
index 1ad6b3d..e8bd6bf 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-28  Mark Wielaard  
+
+   * readelf.c (handle_sysv_hash): Break bucket chain after nchain
+   entries are found.
+   (handle_sysv_hash64): Likewise.
+
 2018-03-27  Mark Wielaard  
 
* readelf.c (attr_callback): Print dwarf_dieoffset as %PRIx64,
diff --git a/src/readelf.c b/src/readelf.c
index 4e35b61..226b19b 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3141,9 +3141,13 @@ handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr 
*shdr, size_t shstrndx)
   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
 {
   Elf32_Word inner = bucket[cnt];
+  Elf32_Word chain_len = 0;
   while (inner > 0 && inner < nchain)
{
  ++nsyms;
+ ++chain_len;
+ if (chain_len > nchain)
+   goto invalid_data;
  if (maxlength < ++lengths[cnt])
++maxlength;
 
@@ -3198,9 +3202,13 @@ handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr 
*shdr, size_t shstrndx)
   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
 {
   Elf64_Xword inner = bucket[cnt];
+  Elf64_Xword chain_len = 0;
   while (inner > 0 && inner < nchain)
{
  ++nsyms;
+ ++chain_len;
+ if (chain_len > nchain)
+   goto invalid_data;
  if (maxlength < ++lengths[cnt])
++maxlength;
 
-- 
1.8.3.1



Re: [PATCH] libdwfl: Use process_vm_readv when available.

2018-03-28 Thread Dmitry V. Levin
On Wed, Mar 28, 2018 at 04:33:26PM +0200, Mark Wielaard wrote:
> On Tue, 2018-03-20 at 23:32 +0100, Mark Wielaard wrote:
> > On Sun, Mar 18, 2018 at 01:43:23AM +0100, Mark Wielaard wrote:
> > > If possible use process_vm_readv to read 4K blocks instead of fetching
> > > each word individually with ptrace. For unwinding this often means we
> > > only have to do one process_vm_readv of the stack instead of dozens of
> > > ptrace calls. There is one 4K cache per process, cleared whenever a
> > > thread is detached.
> > 
> > It seems to work well, but the GCC undefined sanitizer
> > (configure --enable-sanitize-undefined) found an issue in the
> > run-backtrace-native-biarch.sh testcase (from x86_64 to i686)
> > when reading unaligned data. To fix that don't assign to the
> > Dwarf_Word directly when unaligned, but use memcpy (which gcc
> > seems to inline).
> 
> I pushed this to master now. Adding some comments about the word size
> being actually architecture defined even though we use a 64bit
> Dwarf_Word everywhere.

Thanks!


-- 
ldv


signature.asc
Description: PGP signature