[Bug tree-optimization/81694] VRP optimization may introduce buffer overflow vulnerabilities into applications
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81694 --- Comment #7 from Yuan Deng --- When compiled with O0 or O1, the program work well, inspite of val is overflowed, the program is actually very safe, and can not be exploited. But when compiled with O2 or O3, the result is different. The program got a buffer overflow and can be exploited. Actually, In my security reseach work, I have discovered many exploitable vulnerabilities with this root cause in some products. When compiled without VRP optimization, the vulnerability disapeared. But if compiled with VRP optimization, the vulnerability is back. So, I think it's definitely GCC's responsibility. It's GCC's optimization which turn a non-exploitable program into a exploitable program. 2017-08-03 21:17 GMT+08:00 pinskia at gcc dot gnu.org : > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81694 > > --- Comment #6 from Andrew Pinski --- > Overflow cannot be checked after the fact. It needs to be checked before the > overflow has happened. Just like a buffet overflow should not be checked > after. > > -- > You are receiving this mail because: > You reported the bug.
[Bug tree-optimization/81694] VRP optimization may introduce buffer overflow vulnerabilities into applications
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81694 Yuan Deng changed: What|Removed |Added Status|RESOLVED|VERIFIED --- Comment #4 from Yuan Deng --- Inspite of val is overflowed or not, the later check should have avoid this: if( m_var > 0 && m_index > 0 && m_index < (1 << 16)) but did not! I thin it's a very serious problem.
[Bug tree-optimization/81694] VRP optimization may introduce buffer overflow vulnerabilities into applications
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81694 --- Comment #1 from Yuan Deng --- Created attachment 41913 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41913&action=edit patch for this vulnerability
[Bug tree-optimization/81694] New: VRP optimization may introduce buffer overflow vulnerabilities into applications
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) [15.00%]: # val_30 = PHI # DEBUG strm => NULL # DEBUG val => NULL # DEBUG code => NULL this_7(D)->m_index = val_30; if (val_30 > 65535) goto ; [46.00%] else goto ; [54.00%] [8.10%]: # DEBUG strm => NULL # DEBUG val => NULL # DEBUG code => NULL _2 = this_7(D)->m_var; if (_2 > 0) goto ; [67.61%] else goto ; [32.39%] [3.70%]: # DEBUG result => 1