Bug 15836 - Undefined behavior in gas (causes segfault when built with clang)
Summary: Undefined behavior in gas (causes segfault when built with clang)
Status: RESOLVED OBSOLETE
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-13 21:49 UTC by Will Dietz
Modified: 2015-09-09 08:46 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
valgrind log from step 5 (1.59 KB, text/plain)
2013-08-13 21:49 UTC, Will Dietz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Will Dietz 2013-08-13 21:49:41 UTC
Created attachment 7144 [details]
valgrind log from step 5

Description
-----------

The error in question can be seen here:

http://sourceware.org/git/?p=binutils.git;a=blob;f=gas/config/tc-i386-intel.c;h=3f6b057613451839c796ca8a9cdbef2fe6532ec6;hb=HEAD#l432

Where the code assumes unsigned integer wrapping semantics for pointer arithmetic on the variable 'scale' in a number of places.  In particular,
the check:

 432           if (ret && scale && (scale + 1))

Gets optimized to "if (ret && scale)" because it is impossible for "scale + 1" to evaluate to NULL without invoking undefined behavior.  Note that the earlier decrement from NULL is also invalid, and possibly other constructs in related code.

This is is a problem as it results in the conditional being taken when scale is "(int*)-sizeof(int)", which leads to an invalid pointer being dereferenced in resolve_expression().


Steps to reproduce
------------------

1) Obtain and unpack binutils 2.22 or latest via git (tested with 0b0b7b5).
2) Obtain clang 3.3 or latest trunk (from your package manager or build) and modify PATH as appropriate.
3) Configure similar to the following:
  $ CC=clang CXX=clang++ ./configure --disable-werror --enable=ld=no

4) Build.
  $ make -j

5) Run the just-built 'as' using the following program from the testsuite:
$ valgrind gas/as-new --32 gas/testsuite/gas/i386/intelbad.s

6) Observe segfault, see attached 'valgrind.log' for the output of the above command.


Impact
-------

Presently prevents building a functional binutils with recent versions of clang, and is a time-bomb for breaking future builds.  Compilers (including gcc and clang) are known to increasingly take advantage of undefined behavior in newer versions and so this may be an issue in the future even with compilers/platforms that safely build this today.
Comment 1 Jackie Rosen 2014-02-16 18:27:19 UTC Comment hidden (spam)
Comment 2 Nick Clifton 2015-09-09 08:46:40 UTC
Hi Will,

  The offending code was removed in 2013:

    2013-12-03  Tristan Gingold  <gingold@adacore.com>

	* config/tc-i386-intel.c (i386_intel_simplify): Avoid arithmetic
	overflow on pointers.

  Please could you check with the latest version of the binutils sources and if the problem persists, reopen this bug report.

Cheers
  Nick