[Bug binutils/24829] readelf: multi interger overflow in readelf.c and dwarf.c

2019-08-21 Thread nickc at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=24829

Nick Clifton  changed:

   What|Removed |Added

 Status|REOPENED|WAITING

--- Comment #9 from Nick Clifton  ---
(In reply to tfx from comment #7)
Hi tfx,

> You can reproduce it use "readelf -w poc5" with ASAN.
> The crash output show as follow.

Again I cannot reproduce this failure. :-(
Part of the problem is that I am unable to build 32-bit binaries
with address sanitization enabled.  I think that this is a limitation
of the Fedora distribution, but I do not know of any way around the
problem.

>  2063   data = block_start + uvalue;
>  2064   if (block_start + uvalue > end || data < block_start)
>  2065 {
>  2066   warn (_("Corrupt attribute block length: %lx\n"), (long)
> uvalue);
>  2067   uvalue = end - block_start;
>  2068 }


> When "uvalue" is a specific value,  "block_start + uvalue" will cause
> integer overflow. This will cause a wrong "data" value and trigger crash.

I get the "block_start + uvalue" can overflow, but won't this trigger
the "data < block_start" part of the test ?  Which in turn will reset
uvalue to a sane number, and so allow the rest of the code to continue ?


> It seems that reporting this type of bug has no meaning. What do you think?

Oh no, they are definitely worth reporting.  It is just proving to be
very hard for me to track down the cause of the problems and come up
with fixes that will work.

Cheers
  Nick

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
bug-binutils mailing list
bug-binutils@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-binutils


[Bug binutils/24829] readelf: multi interger overflow in readelf.c and dwarf.c

2019-08-21 Thread amodra at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=24829

Alan Modra  changed:

   What|Removed |Added

 CC||amodra at gmail dot com

--- Comment #10 from Alan Modra  ---
> I get the "block_start + uvalue" can overflow, but won't this trigger the 
> "data < block_start" part of the test?

Not necessarily.  The pointers may only be 32 bit, which with a 64-bit uvalue
leads to many values of uvalue > 4G that wrap to a "valid" range.  Pointer
comparisons are a pain.  It's much better in this situation to calculate the
max valid size left then compare that with uvalue.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
bug-binutils mailing list
bug-binutils@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-binutils


[Bug binutils/24829] readelf: multi interger overflow in readelf.c and dwarf.c

2019-08-21 Thread tfx_sec at hotmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=24829

--- Comment #11 from tfx  ---
(In reply to Nick Clifton from comment #9)
> (In reply to tfx from comment #7)
> 
> > You can reproduce it use "readelf -w poc5" with ASAN.
> > The crash output show as follow.
> 
> Again I cannot reproduce this failure. :-(
> Part of the problem is that I am unable to build 32-bit binaries
> with address sanitization enabled.  I think that this is a limitation
> of the Fedora distribution, but I do not know of any way around the
> problem.
> 

You can try to only build part of 32-bit binaries.
CC="clang -m32" CXX="clang -m32" CFLAGS="-m32 -fsanitize=address"
CXXFLAGS="-m32 -fsanitize=address" ./configure
make all-binutils


> >  2063   data = block_start + uvalue;
> >  2064   if (block_start + uvalue > end || data < block_start)
> >  2065 {
> >  2066   warn (_("Corrupt attribute block length: %lx\n"), (long)
> > uvalue);
> >  2067   uvalue = end - block_start;
> >  2068 }
> 
> 
> > When "uvalue" is a specific value,  "block_start + uvalue" will cause
> > integer overflow. This will cause a wrong "data" value and trigger crash.
> 
> I get the "block_start + uvalue" can overflow, but won't this trigger
> the "data < block_start" part of the test ?  Which in turn will reset
> uvalue to a sane number, and so allow the rest of the code to continue ?
> 

I found root of the problem is that "data < block_start" is compiled as "uvalue
< 0" in gcc. When integer overflow, these two statements have different
judgment results.

Debug 32bit readelf with asan use poc5 in gdb 

(gdb) info reg eax   
eax0x26262626   640034342
(gdb) info reg edx
edx0xf5e03b33   -169854157
(gdb)
eax is "uvalue"
edx is "block_start"
data is 0xf5e03b33 + 0x26262626 = 0x1c066159

"data < block_start" is true. But "uvalue < 0" is false, code in braces is
skipped, "uvalue" can't be reset.

It just happens when block_start > 0x8000 and "block_start + uvalue >=
0x1`".

Trigger this crash is difficult, but the overflow can happen.
I only trigger crash in 32bit readelf with ASAN. 


(In reply to Alan Modra from comment #10)
> > I get the "block_start + uvalue" can overflow, but won't this trigger the 
> > "data < block_start" part of the test?
> 
> Not necessarily.  The pointers may only be 32 bit, which with a 64-bit
> uvalue leads to many values of uvalue > 4G that wrap to a "valid" range. 
> Pointer comparisons are a pain.  It's much better in this situation to
> calculate the max valid size left then compare that with uvalue.

I think that's a good solution.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
bug-binutils mailing list
bug-binutils@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-binutils