@@ -37,6 +37,11 @@ class UncalledFunction extends Function {
3737 }
3838}
3939
40+ predicate dataFlowOrTaintFlowFunction ( Function func , FunctionOutput output ) {
41+ func .( DataFlowFunction ) .hasDataFlow ( _, output ) or
42+ func .( TaintFunction ) .hasTaintFlow ( _, output )
43+ }
44+
4045/**
4146 * Holds if `node` is a non-constant source of data flow for non-const format string detection.
4247 * This is defined as either:
@@ -81,24 +86,30 @@ predicate isNonConst(DataFlow::Node node) {
8186 // i.e., functions that with unknown bodies and are not known to define the output through its input
8287 // are considered as possible non-const sources
8388 // The function's output must also not be const to be considered a non-const source
84- exists ( Function func , CallInstruction call |
85- // NOTE: could use `Call` getAnArgument() instead of `CallInstruction` but requires two
86- // variables representing the same call in ordoer to use `callOutput` below.
87- exists ( Expr arg |
88- call .getPositionalArgumentOperand ( _) .getDef ( ) .getUnconvertedResultExpression ( ) = arg and
89- arg = node .asDefiningArgument ( )
89+ (
90+ // Case 1: It's a known dataflow or taintflow function with flow to the return value
91+ exists ( Function func , CallInstruction call |
92+ // NOTE: could use `Call` getAnArgument() instead of `CallInstruction` but requires two
93+ // variables representing the same call in ordoer to use `callOutput` below.
94+ call .getUnconvertedResultExpression ( ) = node .asIndirectExpr ( ) and
95+ func = call .getStaticCallTarget ( ) and
96+ not exists ( FunctionOutput output |
97+ dataFlowOrTaintFlowFunction ( func , output ) and
98+ output .isReturnValueDeref ( ) and
99+ node = callOutput ( call , output )
100+ )
90101 )
91102 or
92- call . getUnconvertedResultExpression ( ) = node . asIndirectExpr ( )
93- |
94- func = call .getStaticCallTarget ( ) and
95- not exists ( FunctionOutput output |
96- // NOTE: we must include dataflow and taintflow. e.g., including only dataflow we will find sprintf
97- // variant function's output are now possible non-const sources
98- pragma [ only_bind_out ] ( func ) . ( DataFlowFunction ) . hasDataFlow ( _ , output ) or
99- pragma [ only_bind_out ] ( func ) . ( TaintFunction ) . hasTaintFlow ( _ , output )
100- |
101- node = callOutput ( call , output )
103+ // Case 1: It's a known dataflow or taintflow function with flow to an output parameter
104+ exists ( Function func , int i , CallInstruction call |
105+ call .getPositionalArgumentOperand ( i ) . getDef ( ) . getUnconvertedResultExpression ( ) =
106+ node . asDefiningArgument ( ) and
107+ func = call . getStaticCallTarget ( ) and
108+ not exists ( FunctionOutput output |
109+ dataFlowOrTaintFlowFunction ( func , output ) and
110+ output . isParameterDeref ( i ) and
111+ node = callOutput ( call , output )
112+ )
102113 )
103114 ) and
104115 not exists ( Call c |
0 commit comments