@@ -25,15 +25,15 @@ import semmle.code.cpp.models.implementations.Strcat
25
25
import DataFlow:: PathGraph
26
26
27
27
/**
28
- * Holds if `fst ` is a string that is used in a format or concatenation function resulting in `snd`,
29
- * and is *not* placed at the start of the resulting string. This indicates that the author did not
30
- * expect `fst ` to control what program is run if the resulting string is eventually interpreted as
31
- * a command line, for example as an argument to `system`.
28
+ * Holds if `incoming ` is a string that is used in a format or concatenation function resulting
29
+ * in `outgoing`, and is *not* placed at the start of the resulting string. This indicates that
30
+ * the author did not expect `incoming ` to control what program is run if the resulting string
31
+ * is eventually interpreted as a command line, for example as an argument to `system`.
32
32
*/
33
- predicate interestingConcatenation ( DataFlow:: Node fst , DataFlow:: Node snd ) {
33
+ predicate interestingConcatenation ( DataFlow:: Node incoming , DataFlow:: Node outgoing ) {
34
34
exists ( FormattingFunctionCall call , int index , FormatLiteral literal |
35
- fst .asIndirectArgument ( ) = call .getConversionArgument ( index ) and
36
- snd .asDefiningArgument ( ) = call .getOutputArgument ( false ) and
35
+ incoming .asIndirectArgument ( ) = call .getConversionArgument ( index ) and
36
+ outgoing .asDefiningArgument ( ) = call .getOutputArgument ( false ) and
37
37
literal = call .getFormat ( ) and
38
38
not literal .getConvSpecOffset ( index ) = 0 and
39
39
literal .getConversionChar ( index ) = [ "s" , "S" ]
@@ -42,16 +42,16 @@ predicate interestingConcatenation(DataFlow::Node fst, DataFlow::Node snd) {
42
42
// strcat and friends
43
43
exists ( StrcatFunction strcatFunc , Call call |
44
44
call .getTarget ( ) = strcatFunc and
45
- fst .asIndirectArgument ( ) = call .getArgument ( strcatFunc .getParamSrc ( ) ) and
46
- snd .asDefiningArgument ( ) = call .getArgument ( strcatFunc .getParamDest ( ) )
45
+ incoming .asIndirectArgument ( ) = call .getArgument ( strcatFunc .getParamSrc ( ) ) and
46
+ outgoing .asDefiningArgument ( ) = call .getArgument ( strcatFunc .getParamDest ( ) )
47
47
)
48
48
or
49
49
exists ( Call call , Operator op |
50
50
call .getTarget ( ) = op and
51
51
op .hasQualifiedName ( "std" , "operator+" ) and
52
52
op .getType ( ) .( UserType ) .hasQualifiedName ( "std" , "basic_string" ) and
53
- fst .asIndirectArgument ( ) = call .getArgument ( 1 ) and // left operand
54
- call = snd .asInstruction ( ) .getUnconvertedResultExpression ( )
53
+ incoming .asIndirectArgument ( ) = call .getArgument ( 1 ) and // left operand
54
+ call = outgoing .asInstruction ( ) .getUnconvertedResultExpression ( )
55
55
)
56
56
}
57
57
@@ -60,22 +60,23 @@ class ConcatState extends DataFlow::FlowState {
60
60
}
61
61
62
62
class ExecState extends DataFlow:: FlowState {
63
- DataFlow:: Node fst ;
64
- DataFlow:: Node snd ;
63
+ DataFlow:: Node incoming ;
64
+ DataFlow:: Node outgoing ;
65
65
66
66
ExecState ( ) {
67
67
this =
68
- "ExecState (" + fst .getLocation ( ) + " | " + fst + ", " + snd .getLocation ( ) + " | " + snd + ")" and
69
- interestingConcatenation ( pragma [ only_bind_into ] ( fst ) , pragma [ only_bind_into ] ( snd ) )
68
+ "ExecState (" + incoming .getLocation ( ) + " | " + incoming + ", " + outgoing .getLocation ( ) +
69
+ " | " + outgoing + ")" and
70
+ interestingConcatenation ( pragma [ only_bind_into ] ( incoming ) , pragma [ only_bind_into ] ( outgoing ) )
70
71
}
71
72
72
- DataFlow:: Node getFstNode ( ) { result = fst }
73
+ DataFlow:: Node getIncomingNode ( ) { result = incoming }
73
74
74
- DataFlow:: Node getSndNode ( ) { result = snd }
75
+ DataFlow:: Node getOutgoingNode ( ) { result = outgoing }
75
76
76
77
/** Holds if this is a possible `ExecState` for `sink`. */
77
78
predicate isFeasibleForSink ( DataFlow:: Node sink ) {
78
- any ( ExecStateConfiguration conf ) .hasFlow ( snd , sink )
79
+ any ( ExecStateConfiguration conf ) .hasFlow ( outgoing , sink )
79
80
}
80
81
}
81
82
@@ -93,7 +94,7 @@ class ExecStateConfiguration extends TaintTracking2::Configuration {
93
94
ExecStateConfiguration ( ) { this = "ExecStateConfiguration" }
94
95
95
96
override predicate isSource ( DataFlow:: Node source ) {
96
- exists ( ExecState state | state . getSndNode ( ) = source )
97
+ any ( ExecState state ) . getOutgoingNode ( ) = source
97
98
}
98
99
99
100
override predicate isSink ( DataFlow:: Node sink ) { isSinkImpl ( sink , _, _) }
@@ -121,8 +122,8 @@ class ExecTaintConfiguration extends TaintTracking::Configuration {
121
122
DataFlow:: FlowState state2
122
123
) {
123
124
state1 instanceof ConcatState and
124
- state2 .( ExecState ) .getFstNode ( ) = node1 and
125
- state2 .( ExecState ) .getSndNode ( ) = node2
125
+ state2 .( ExecState ) .getIncomingNode ( ) = node1 and
126
+ state2 .( ExecState ) .getOutgoingNode ( ) = node2
126
127
}
127
128
128
129
override predicate isSanitizer ( DataFlow:: Node node , DataFlow:: FlowState state ) {
@@ -146,7 +147,7 @@ where
146
147
conf .hasFlowPath ( sourceNode , sinkNode ) and
147
148
taintCause = sourceNode .getNode ( ) .( FlowSource ) .getSourceType ( ) and
148
149
isSinkImpl ( sinkNode .getNode ( ) , command , callChain ) and
149
- concatResult = sinkNode .getState ( ) .( ExecState ) .getSndNode ( )
150
+ concatResult = sinkNode .getState ( ) .( ExecState ) .getOutgoingNode ( )
150
151
select command , sourceNode , sinkNode ,
151
152
"This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to "
152
153
+ callChain + "." , sourceNode , "user input (" + taintCause + ")" , concatResult ,
0 commit comments