https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81694

            Bug ID: 81694
           Summary: VRP optimization may introduce buffer overflow
                    vulnerabilities into applications
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: scdengyuan at gmail dot com
  Target Milestone: ---

Created attachment 41912
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41912&action=edit
proof of concept

function extract_range_from_multiplicative_op_1 in tree-vrp.c in GNU Compiler
Collection (gcc) from 4.7.0 to 7.1.0 improperly handles integer overflow, which
might introduce buffer overflow vulnerabilities into applications.

When O2 or O3 flag is set, VRP optimization is enabled.
in my poc:
    m_index = ReadNumber(m_strm);
    if( m_index > 65535 )
        return false;

    // int m_index can be overflowed to negative but VRP think it's between
[48, +INF(OVF)], and ignored checking in next line 
    if( m_var > 0 && m_index > 0 && m_index < (1 << 16)) //this line was
optimized to "if( m_var>0 )"
    // so negative m_index can bypass the check and return true



Value ranges after VRP:

_1: ~[0B, 0B]
_2: VARYING
_3: [0, +INF]
.MEM_4: VARYING
this_7(D): ~[0B, 0B]
_9: VARYING
_11: [48, 57]  EQUIVALENCES: { _15 } (1 elements)
this_12: ~[0B, 0B]  EQUIVALENCES: { this_7(D) } (1 elements)
_15: VARYING
code.1_16: [0, +INF]
_17: [0, +INF]
val_18: [0, +INF(OVF)]
_19: [0, +INF(OVF)]
code_20: [48, 57]  EQUIVALENCES: { } (0 elements)
val_21: [48, +INF(OVF)]
_22: VARYING
code.3_23: [0, +INF]
_24: [0, +INF]
_25: [48, 57]  EQUIVALENCES: { _15 } (1 elements)
.MEM_26: VARYING
.MEM_27: VARYING
val_30: [48, +INF(OVF)]
_31: [48, 57]  EQUIVALENCES: { _22 } (1 elements)
val_32: [48, 65535]  EQUIVALENCES: { val_30 } (1 elements)

  <bb 7> [15.00%]:
  # val_30 = PHI <val_21(6)>
  # DEBUG strm => NULL
  # DEBUG val => NULL
  # DEBUG code => NULL
  this_7(D)->m_index = val_30;
  if (val_30 > 65535)
    goto <bb 10>; [46.00%]
  else
    goto <bb 8>; [54.00%]

  <bb 8> [8.10%]:
  # DEBUG strm => NULL
  # DEBUG val => NULL
  # DEBUG code => NULL
  _2 = this_7(D)->m_var;
  if (_2 > 0)
    goto <bb 9>; [67.61%]
  else
    goto <bb 10>; [32.39%]

  <bb 9> [3.70%]:
  # DEBUG result => 1

Reply via email to