Skip to content

Commit 91ce02a

Browse files
Java: Fix bug involving varadic parameters
1 parent 79209af commit 91ce02a

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,23 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
257257
)
258258
}
259259

260+
/**
261+
* Converts an argument index to a formal parameter index.
262+
* This is relevant for varadic methods.
263+
*/
264+
private int argToParam(MethodAccess ma, int arg) {
265+
exists(ma.getArgument(arg)) and
266+
exists(Method m | m = ma.getMethod() |
267+
if m.isVarargs() and arg >= m.getNumberOfParameters()
268+
then result = m.getNumberOfParameters() - 2
269+
else result = arg
270+
)
271+
}
272+
260273
/** Access to a method that passes taint from qualifier to argument. */
261274
private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
262275
exists(MethodAccess ma, int arg |
263-
taintPreservingQualifierToArgument(ma.getMethod(), arg) and
276+
taintPreservingQualifierToArgument(ma.getMethod(), argToParam(ma, arg)) and
264277
tracked = ma.getQualifier() and
265278
sink = ma.getArgument(arg)
266279
)
@@ -394,7 +407,7 @@ private predicate unsafeEscape(MethodAccess ma) {
394407
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
395408
exists(Method m, int i |
396409
m = sink.getMethod() and
397-
taintPreservingArgumentToMethod(m, i) and
410+
taintPreservingArgumentToMethod(m, argToParam(sink, i)) and
398411
tracked = sink.getArgument(i)
399412
)
400413
or
@@ -519,7 +532,7 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
519532
*/
520533
private predicate argToArgStep(Expr tracked, Expr sink) {
521534
exists(MethodAccess ma, Method method, int input, int output |
522-
taintPreservingArgToArg(method, input, output) and
535+
taintPreservingArgToArg(method, argToParam(ma, input), argToParam(ma, output)) and
523536
ma.getMethod() = method and
524537
ma.getArgument(input) = tracked and
525538
ma.getArgument(output) = sink
@@ -567,7 +580,7 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
567580
*/
568581
private predicate argToQualifierStep(Expr tracked, Expr sink) {
569582
exists(Method m, int i, MethodAccess ma |
570-
taintPreservingArgumentToQualifier(m, i) and
583+
taintPreservingArgumentToQualifier(m, argToParam(ma, i)) and
571584
ma.getMethod() = m and
572585
tracked = ma.getArgument(i) and
573586
sink = ma.getQualifier()

java/ql/test/library-tests/dataflow/taint-format/A.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public static void test1() {
1414
good.formatted("a", bad, "b", good);
1515
String.format("%s%s", bad, good);
1616
String.format("%s", good);
17+
String.format("%s %s %s %s %s %s %s %s %s %s ", "a", "a", "a", "a", "a", "a", "a", "a", "a", bad);
1718
}
1819

1920
public static void test2() {

java/ql/test/library-tests/dataflow/taint-format/test.expected

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,26 @@
77
| A.java:10:22:10:28 | taint(...) | A.java:15:9:15:40 | format(...) |
88
| A.java:10:22:10:28 | taint(...) | A.java:15:9:15:40 | new ..[] { .. } |
99
| A.java:10:22:10:28 | taint(...) | A.java:15:31:15:33 | bad |
10-
| A.java:20:22:20:28 | taint(...) | A.java:20:22:20:28 | taint(...) |
11-
| A.java:20:22:20:28 | taint(...) | A.java:24:9:24:9 | f [post update] |
12-
| A.java:20:22:20:28 | taint(...) | A.java:24:9:24:27 | format(...) |
13-
| A.java:20:22:20:28 | taint(...) | A.java:24:9:24:27 | new ..[] { .. } |
14-
| A.java:20:22:20:28 | taint(...) | A.java:24:24:24:26 | bad |
15-
| A.java:20:22:20:28 | taint(...) | A.java:25:9:25:9 | f |
16-
| A.java:20:22:20:28 | taint(...) | A.java:25:9:25:20 | toString(...) |
17-
| A.java:29:22:29:28 | taint(...) | A.java:29:22:29:28 | taint(...) |
18-
| A.java:29:22:29:28 | taint(...) | A.java:33:9:33:10 | sb |
19-
| A.java:29:22:29:28 | taint(...) | A.java:33:9:33:21 | toString(...) |
20-
| A.java:29:22:29:28 | taint(...) | A.java:34:9:34:9 | f [post update] |
21-
| A.java:29:22:29:28 | taint(...) | A.java:34:9:34:27 | format(...) |
22-
| A.java:29:22:29:28 | taint(...) | A.java:34:9:34:27 | new ..[] { .. } |
23-
| A.java:29:22:29:28 | taint(...) | A.java:34:24:34:26 | bad |
24-
| A.java:29:22:29:28 | taint(...) | A.java:35:9:35:10 | sb |
25-
| A.java:29:22:29:28 | taint(...) | A.java:35:9:35:21 | toString(...) |
26-
| A.java:39:22:39:28 | taint(...) | A.java:39:22:39:28 | taint(...) |
27-
| A.java:39:22:39:28 | taint(...) | A.java:42:18:42:20 | bad |
28-
| A.java:39:22:39:28 | taint(...) | A.java:43:9:43:46 | new ..[] { .. } |
29-
| A.java:39:22:39:28 | taint(...) | A.java:43:43:43:45 | bad |
10+
| A.java:10:22:10:28 | taint(...) | A.java:17:9:17:105 | format(...) |
11+
| A.java:10:22:10:28 | taint(...) | A.java:17:9:17:105 | new ..[] { .. } |
12+
| A.java:10:22:10:28 | taint(...) | A.java:17:102:17:104 | bad |
13+
| A.java:21:22:21:28 | taint(...) | A.java:21:22:21:28 | taint(...) |
14+
| A.java:21:22:21:28 | taint(...) | A.java:25:9:25:9 | f [post update] |
15+
| A.java:21:22:21:28 | taint(...) | A.java:25:9:25:27 | format(...) |
16+
| A.java:21:22:21:28 | taint(...) | A.java:25:9:25:27 | new ..[] { .. } |
17+
| A.java:21:22:21:28 | taint(...) | A.java:25:24:25:26 | bad |
18+
| A.java:21:22:21:28 | taint(...) | A.java:26:9:26:9 | f |
19+
| A.java:21:22:21:28 | taint(...) | A.java:26:9:26:20 | toString(...) |
20+
| A.java:30:22:30:28 | taint(...) | A.java:30:22:30:28 | taint(...) |
21+
| A.java:30:22:30:28 | taint(...) | A.java:34:9:34:10 | sb |
22+
| A.java:30:22:30:28 | taint(...) | A.java:34:9:34:21 | toString(...) |
23+
| A.java:30:22:30:28 | taint(...) | A.java:35:9:35:9 | f [post update] |
24+
| A.java:30:22:30:28 | taint(...) | A.java:35:9:35:27 | format(...) |
25+
| A.java:30:22:30:28 | taint(...) | A.java:35:9:35:27 | new ..[] { .. } |
26+
| A.java:30:22:30:28 | taint(...) | A.java:35:24:35:26 | bad |
27+
| A.java:30:22:30:28 | taint(...) | A.java:36:9:36:10 | sb |
28+
| A.java:30:22:30:28 | taint(...) | A.java:36:9:36:21 | toString(...) |
29+
| A.java:40:22:40:28 | taint(...) | A.java:40:22:40:28 | taint(...) |
30+
| A.java:40:22:40:28 | taint(...) | A.java:43:18:43:20 | bad |
31+
| A.java:40:22:40:28 | taint(...) | A.java:44:9:44:46 | new ..[] { .. } |
32+
| A.java:40:22:40:28 | taint(...) | A.java:44:43:44:45 | bad |

0 commit comments

Comments
 (0)