1010 * external/cwe/cwe-295
1111 */
1212
13-
1413import cpp
1514import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1615import semmle.code.cpp.controlflow.IRGuards
@@ -19,70 +18,70 @@ import semmle.code.cpp.controlflow.IRGuards
1918 * A call to `SSL_get_peer_certificate`.
2019 */
2120class SSLGetPeerCertificateCall extends FunctionCall {
22- SSLGetPeerCertificateCall ( ) {
23- getTarget ( ) .getName ( ) = "SSL_get_peer_certificate" // SSL_get_peer_certificate(ssl)
24- }
21+ SSLGetPeerCertificateCall ( ) {
22+ getTarget ( ) .getName ( ) = "SSL_get_peer_certificate" // SSL_get_peer_certificate(ssl)
23+ }
2524
26- Expr getSSLArgument ( ) { result = getArgument ( 0 ) }
25+ Expr getSSLArgument ( ) { result = getArgument ( 0 ) }
2726}
2827
2928/**
3029 * A call to `SSL_get_verify_result`.
3130 */
3231class SSLGetVerifyResultCall extends FunctionCall {
33- SSLGetVerifyResultCall ( ) {
34- getTarget ( ) .getName ( ) = "SSL_get_verify_result" // SSL_get_peer_certificate(ssl)
35- }
32+ SSLGetVerifyResultCall ( ) {
33+ getTarget ( ) .getName ( ) = "SSL_get_verify_result" // SSL_get_peer_certificate(ssl)
34+ }
3635
37- Expr getSSLArgument ( ) { result = getArgument ( 0 ) }
36+ Expr getSSLArgument ( ) { result = getArgument ( 0 ) }
3837}
3938
4039/**
4140 * Holds if the SSL object passed into `SSL_get_peer_certificate` is checked with
4241 * `SSL_get_verify_result` entering `node`.
4342 */
4443predicate resultIsChecked ( SSLGetPeerCertificateCall getCertCall , ControlFlowNode node ) {
45- exists ( Expr ssl , SSLGetVerifyResultCall check |
46- ssl = globalValueNumber ( getCertCall .getSSLArgument ( ) ) .getAnExpr ( ) and
47- ssl = check .getSSLArgument ( ) and
48- node = check
49- )
44+ exists ( Expr ssl , SSLGetVerifyResultCall check |
45+ ssl = globalValueNumber ( getCertCall .getSSLArgument ( ) ) .getAnExpr ( ) and
46+ ssl = check .getSSLArgument ( ) and
47+ node = check
48+ )
5049}
5150
5251/**
5352 * Holds if the certificate returned by `SSL_get_peer_certificate` is found to be
5453 * `0` on the edge `node1` to `node2`.
5554 */
56- predicate certIsZero ( SSLGetPeerCertificateCall getCertCall , ControlFlowNode node1 , ControlFlowNode node2 ) {
57- exists ( GuardCondition guard , Expr cert |
58- cert = globalValueNumber ( getCertCall ) . getAnExpr ( ) and
59- (
60- exists ( Expr zero |
61- zero . getValue ( ) . toInt ( ) = 0 and
62- node1 = guard and
63- (
64- (
65- // if (cert == zero) {
66- guard . comparesEq ( cert , zero , 0 , true , true ) and
67- node2 = guard .getATrueSuccessor ( )
68- ) or (
69- // if (cert != zero) { }
70- guard . comparesEq ( cert , zero , 0 , false , true ) and
71- node2 = guard .getAFalseSuccessor ( )
72- )
73- )
74- ) or (
75- // if (cert) { }
76- guard = cert and
77- node1 = guard and
78- node2 = guard . getAFalseSuccessor ( )
79- ) or (
80- // if (!cert) {
81- node1 = guard . getParent ( ) and
82- node2 = guard .getParent ( ) . ( NotExpr ) . getATrueSuccessor ( )
83- )
84- )
85- )
55+ predicate certIsZero (
56+ SSLGetPeerCertificateCall getCertCall , ControlFlowNode node1 , ControlFlowNode node2
57+ ) {
58+ exists ( GuardCondition guard , Expr cert |
59+ cert = globalValueNumber ( getCertCall ) . getAnExpr ( ) and
60+ (
61+ exists ( Expr zero |
62+ zero . getValue ( ) . toInt ( ) = 0 and
63+ node1 = guard and
64+ (
65+ // if (cert == zero) {
66+ guard .comparesEq ( cert , zero , 0 , true , true ) and
67+ node2 = guard . getATrueSuccessor ( )
68+ or
69+ // if (cert != zero) { }
70+ guard .comparesEq ( cert , zero , 0 , false , true ) and
71+ node2 = guard . getAFalseSuccessor ( )
72+ )
73+ )
74+ or
75+ // if ( cert) { }
76+ guard = cert and
77+ node1 = guard and
78+ node2 = guard . getAFalseSuccessor ( )
79+ or
80+ // if (!cert) {
81+ node1 = guard .getParent ( ) and
82+ node2 = guard . getParent ( ) . ( NotExpr ) . getATrueSuccessor ( )
83+ )
84+ )
8685}
8786
8887/**
@@ -91,34 +90,33 @@ predicate certIsZero(SSLGetPeerCertificateCall getCertCall, ControlFlowNode node
9190 * `SSL_get_peer_certificate` and at the start and end of `BasicBlock`s.
9291 */
9392predicate certNotChecked ( SSLGetPeerCertificateCall getCertCall , ControlFlowNode node ) {
94- (
95- // cert is not checked at the call to `SSL_get_peer_certificate`
96- node = getCertCall
97- ) or exists ( BasicBlock bb , int pos |
98- // flow to end of a `BasicBlock`
99- certNotChecked ( getCertCall , bb .getNode ( pos ) ) and
100- node = bb .getEnd ( ) and
101-
102- // check for barrier node
103- not exists ( int pos2 |
104- pos2 > pos and
105- resultIsChecked ( getCertCall , bb . getNode ( pos2 ) )
106- )
107- ) or exists ( BasicBlock pred , BasicBlock bb |
108- // flow from the end of one ` BasicBlock` to the beginning of a successor
109- certNotChecked ( getCertCall , pred . getEnd ( ) ) and
110- bb = pred .getASuccessor ( ) and
111- node = bb . getStart ( ) and
112-
113- // check for barrier bb
114- not certIsZero ( getCertCall , pred .getEnd ( ) , bb .getStart ( ) )
115- )
93+ // cert is not checked at the call to `SSL_get_peer_certificate`
94+ node = getCertCall
95+ or
96+ exists ( BasicBlock bb , int pos |
97+ // flow to end of a `BasicBlock`
98+ certNotChecked ( getCertCall , bb .getNode ( pos ) ) and
99+ node = bb .getEnd ( ) and
100+ // check for barrier node
101+ not exists ( int pos2 |
102+ pos2 > pos and
103+ resultIsChecked ( getCertCall , bb . getNode ( pos2 ) )
104+ )
105+ )
106+ or
107+ exists ( BasicBlock pred , BasicBlock bb |
108+ // flow from the end of one `BasicBlock` to the beginning of a successor
109+ certNotChecked ( getCertCall , pred .getEnd ( ) ) and
110+ bb = pred . getASuccessor ( ) and
111+ node = bb . getStart ( ) and
112+ // check for barrier bb
113+ not certIsZero ( getCertCall , pred .getEnd ( ) , bb .getStart ( ) )
114+ )
116115}
117116
118- from
119- SSLGetPeerCertificateCall getCertCall , ControlFlowNode node
117+ from SSLGetPeerCertificateCall getCertCall , ControlFlowNode node
120118where
121- certNotChecked ( getCertCall , node ) and
122- node instanceof Function // (function exit)
123- select
124- getCertCall , "This " + getCertCall .toString ( ) + " is not followed by a call to SSL_get_verify_result."
119+ certNotChecked ( getCertCall , node ) and
120+ node instanceof Function // (function exit)
121+ select getCertCall ,
122+ "This " + getCertCall .toString ( ) + " is not followed by a call to SSL_get_verify_result."
0 commit comments