Skip to content

Commit c950e26

Browse files
committed
C++: Rewrite 'cpp/cpp/tainted-arithmetic' away from DefaultTaintTracking.
1 parent 8be6aed commit c950e26

File tree

3 files changed

+120
-87
lines changed

3 files changed

+120
-87
lines changed

cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@
1414

1515
import cpp
1616
import semmle.code.cpp.security.Overflow
17-
import semmle.code.cpp.security.Security
18-
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
19-
import TaintedWithPath
17+
import semmle.code.cpp.dataflow.new.TaintTracking
18+
import semmle.code.cpp.dataflow.new.DataFlow
19+
import semmle.code.cpp.ir.IR
20+
import semmle.code.cpp.controlflow.IRGuards as IRGuards
21+
import semmle.code.cpp.security.FlowSources as FS
2022
import Bounded
23+
import Flow::PathGraph
2124

2225
bindingset[op]
2326
predicate missingGuard(Operation op, Expr e, string effect) {
@@ -28,28 +31,90 @@ predicate missingGuard(Operation op, Expr e, string effect) {
2831
not e instanceof VariableAccess and effect = "overflow"
2932
}
3033

31-
class Configuration extends TaintTrackingConfiguration {
32-
override predicate isSink(Element e) {
33-
exists(Operation op |
34-
missingGuard(op, e, _) and
35-
op.getAnOperand() = e
36-
|
37-
op instanceof UnaryArithmeticOperation or
38-
op instanceof BinaryArithmeticOperation or
39-
op instanceof AssignArithmeticOperation
40-
)
41-
}
34+
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
35+
36+
predicate isSink(DataFlow::Node sink, Operation op, Expr e) {
37+
e = sink.asExpr() and
38+
missingGuard(op, e, _) and
39+
op.getAnOperand() = e and
40+
(
41+
op instanceof UnaryArithmeticOperation or
42+
op instanceof BinaryArithmeticOperation or
43+
op instanceof AssignArithmeticOperation
44+
)
45+
}
46+
47+
predicate hasUpperBoundsCheck(Variable var) {
48+
exists(RelationalOperation oper, VariableAccess access |
49+
oper.getAnOperand() = access and
50+
access.getTarget() = var and
51+
// Comparing to 0 is not an upper bound check
52+
not oper.getAnOperand().getValue() = "0"
53+
)
54+
}
55+
56+
predicate constantInstruction(Instruction instr) {
57+
instr instanceof ConstantInstruction or
58+
constantInstruction(instr.(UnaryInstruction).getUnary())
59+
}
60+
61+
predicate readsVariable(LoadInstruction load, Variable var) {
62+
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
63+
}
4264

43-
override predicate isBarrier(Expr e) {
44-
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
65+
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
66+
exists(Instruction instr | instr = node.asInstruction() |
67+
readsVariable(instr, checkedVar) and
68+
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
69+
)
70+
}
71+
72+
module Config implements DataFlow::ConfigSig {
73+
predicate isSource(DataFlow::Node source) { isSource(source, _) }
74+
75+
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
76+
77+
predicate isBarrier(DataFlow::Node node) {
78+
exists(StoreInstruction store | store = node.asInstruction() |
79+
// Block flow to "likely small expressions"
80+
bounded(store.getSourceValue().getUnconvertedResultExpression())
81+
or
82+
// Block flow to "small types"
83+
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
84+
)
85+
or
86+
// Block flow if there's an upper bound check of the variable anywhere in the program
87+
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
88+
readsVariable(instr, checkedVar) and
89+
hasUpperBoundsCheck(checkedVar)
90+
)
91+
or
92+
// Block flow if the node is guarded by an equality check
93+
exists(Variable checkedVar, Operand access |
94+
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
95+
readsVariable(access.getDef(), checkedVar)
96+
)
97+
or
98+
// Block flow to any binary instruction whose operands are both non-constants.
99+
exists(BinaryInstruction iTo |
100+
iTo = node.asInstruction() and
101+
not constantInstruction(iTo.getLeft()) and
102+
not constantInstruction(iTo.getRight()) and
103+
// propagate taint from either the pointer or the offset, regardless of constantness
104+
not iTo instanceof PointerArithmeticInstruction
105+
)
45106
}
46107
}
47108

48-
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
109+
module Flow = TaintTracking::Global<Config>;
110+
111+
from
112+
Expr e, string effect, Flow::PathNode source, Flow::PathNode sink, Operation op, string sourceType
49113
where
50-
taintedWithPath(origin, e, sourceNode, sinkNode) and
51-
op.getAnOperand() = e and
114+
Flow::flowPath(source, sink) and
115+
isSource(source.getNode(), sourceType) and
116+
isSink(sink.getNode(), op, e) and
52117
missingGuard(op, e, effect)
53-
select e, sourceNode, sinkNode,
118+
select e, source, sink,
54119
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
55-
origin, "User-provided value"
120+
source, sourceType
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
edges
2-
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
3-
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
42
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
5-
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
6-
subpaths
73
nodes
8-
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
94
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
105
| examples.cpp:66:11:66:14 | data | semmle.label | data |
11-
| examples.cpp:66:11:66:14 | data | semmle.label | data |
6+
subpaths
127
#select
13-
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |
8+
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |
Lines changed: 32 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,59 @@
11
edges
22
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
3-
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
4-
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
53
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
64
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
7-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
8-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
9-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
10-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
11-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
12-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
13-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
14-
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
15-
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
165
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
176
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
18-
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
19-
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
7+
| test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
8+
| test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
9+
| test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
2010
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
2111
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
22-
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
23-
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
2412
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
2513
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
26-
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
27-
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
28-
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
29-
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
30-
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
31-
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
32-
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
33-
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
34-
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
35-
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
36-
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
37-
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
38-
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
39-
subpaths
14+
| test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
15+
| test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
16+
| test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
4017
nodes
4118
| test2.cpp:12:21:12:21 | v | semmle.label | v |
4219
| test2.cpp:14:11:14:11 | v | semmle.label | v |
43-
| test2.cpp:14:11:14:11 | v | semmle.label | v |
44-
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
4520
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
4621
| test2.cpp:27:13:27:13 | v | semmle.label | v |
47-
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
48-
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
4922
| test2.cpp:36:9:36:14 | fgets output argument | semmle.label | fgets output argument |
5023
| test2.cpp:39:9:39:11 | num | semmle.label | num |
51-
| test2.cpp:39:9:39:11 | num | semmle.label | num |
52-
| test2.cpp:40:3:40:5 | num | semmle.label | num |
5324
| test2.cpp:40:3:40:5 | num | semmle.label | num |
25+
| test3.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
5426
| test5.cpp:5:5:5:17 | getTaintedInt indirection | semmle.label | getTaintedInt indirection |
55-
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
56-
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
5727
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
5828
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
59-
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
6029
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
6130
| test5.cpp:19:6:19:6 | y | semmle.label | y |
62-
| test5.cpp:19:6:19:6 | y | semmle.label | y |
63-
| test.c:11:29:11:32 | argv | semmle.label | argv |
64-
| test.c:11:29:11:32 | argv | semmle.label | argv |
65-
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
31+
| test.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
6632
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
67-
| test.c:41:17:41:20 | argv | semmle.label | argv |
68-
| test.c:41:17:41:20 | argv | semmle.label | argv |
6933
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
70-
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
71-
| test.c:51:17:51:20 | argv | semmle.label | argv |
72-
| test.c:51:17:51:20 | argv | semmle.label | argv |
73-
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
7434
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
35+
subpaths
7536
#select
76-
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
77-
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
78-
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
79-
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
80-
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | buf | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
81-
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
82-
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
83-
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:11:29:11:32 | argv | User-provided value |
84-
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:11:29:11:32 | argv | User-provided value |
85-
| test.c:44:7:44:10 | len2 | test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:41:17:41:20 | argv | User-provided value |
86-
| test.c:54:7:54:10 | len3 | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:51:17:51:20 | argv | User-provided value |
37+
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
38+
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
39+
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
40+
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
41+
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
42+
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
43+
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
44+
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
45+
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
46+
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
47+
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
48+
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
49+
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
50+
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
51+
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
52+
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
53+
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
54+
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
55+
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
56+
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
57+
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
58+
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
59+
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |

0 commit comments

Comments
 (0)