From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 1EAF5398300B; Thu, 22 Oct 2020 11:06:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1EAF5398300B From: "mark at klomp dot org" To: elfutils-devel@sourceware.org Subject: [Bug libdw/26773] New: sleb128 values near INT64_MAX/MIN not correctly read Date: Thu, 22 Oct 2020 11:06:27 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: elfutils X-Bugzilla-Component: libdw X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: mark at klomp dot org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Oct 2020 11:06:28 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D26773 Bug ID: 26773 Summary: sleb128 values near INT64_MAX/MIN not correctly read Product: elfutils Version: unspecified Status: NEW Severity: normal Priority: P2 Component: libdw Assignee: unassigned at sourceware dot org Reporter: mark at klomp dot org CC: elfutils-devel at sourceware dot org, tromey at sourcew= are dot org Target Milestone: --- sleb128 values near INT64_MAX/MIN are not correctly read since: commit 65a211f9028304757df8f4fa7cb3cc77d1501420 Author: Mark Wielaard Date: Wed Apr 22 12:28:30 2015 +0200 libdw: Undefined behavior in get_sleb128_step. gcc -fsanitize=3Dundefined pointed out that for too big sleb128 values = we could shift into the sign bit. So for sleb128 values that have to fit in a (signed) int64_t variable reduce the max number of steps by one. https://bugzilla.redhat.com/show_bug.cgi?id=3D1170810#c29 Signed-off-by: Mark Wielaard The idea was the we didn't want to shift 1 << (9 * 7) since that would shif= t 63 places in a signed value (which is undefined behavior). Where 9 is the numb= er of bytes/steps (counting from zero). But sleb128 values near INT64_MIN/MAX = are represented by 10 bytes. Where the 10th byte doesn't have its high bit set = to indicate it is the last one. So for sleb128 values that use 10 bytes we fai= l to read all and return INT64_MAX. The reason we haven't seen this before is because normally using data8 is cheaper for representing such values (if we know the type is signed). But w= ith DWARF5 we might be able to share the value between DIEs using DW_FORM_implicit_const (which is represented in the abbrev itself using an sleb128). An example that triggers this is: #include int foo () { int64_t maxA, maxB, maxC; maxA =3D maxB =3D maxC =3D INT64_MAX - 16; /* 9223372036854775791 */ int64_t minA, minB, minC; minA =3D minB =3D minC =3D INT64_MIN + 16; /* -9223372036854775792 */ return (maxA + maxB + maxC + minA + minB + minC); } compiled with gcc -gdwarf-5 -g -O2 -c consts.c $ eu-readelf --debug-dump=3Dabbrev consts.o DWARF section [ 6] '.debug_abbrev' at offset 0x114: [ Code] Abbreviation section at offset 0: [ 1] offset: 0, children: no, tag: base_type attr: byte_size, form: data1, offset: 0 attr: encoding, form: data1, offset: 0x2 attr: name, form: strp, offset: 0x4 [ 2] offset: 11, children: no, tag: variable attr: name, form: strp, offset: 0xb attr: decl_file, form: implicit_const (1), offset: 0xd attr: decl_line, form: implicit_const (5), offset: 0x10 attr: decl_column, form: data1, offset: 0x13 attr: type, form: ref4, offset: 0x15 attr: const_value, form: implicit_const (9223372036854775807), offset: 0x17 Abbreviation section at offset 40: [ 3] offset: 40, children: no, tag: variable attr: name, form: strp, offset: 0x28 attr: decl_file, form: implicit_const (1), offset: 0x2a attr: decl_line, form: implicit_const (8), offset: 0x2d attr: decl_column, form: data1, offset: 0x30 attr: type, form: ref4, offset: 0x32 attr: const_value, form: implicit_const (9223372036854775807), offset: 0x34 attr: call_origin, form: ??? (0), offset: 0x3f attr: ??? (0), form: block4, offset: 0x41 [...] Note how both values are read as INT64_MAX and that after (what is supposed= to be the negative value -9223372036854775792) the rest of the abbrev is read wrongly: $ eu-readelf --debug-dump=3Dinfo consts.o DWARF section [ 4] '.debug_info' at offset 0x46: [Offset] Compilation unit at offset 0: Version: 5, Abbreviation section offset: 0, Address size: 8, Offset size: 4 Unit type: compile (1) eu-readelf: cannot get tag of DIE at offset [c] in section '.debug_info': invalid DWARF We have to allow reading 10-byte sleb128 values without triggering undefined behavior. --=20 You are receiving this mail because: You are on the CC list for the bug.=