Skip to content

Commit 9a365d8

Browse files
committed
C++: Tighten up the heuristic in cpp/unterminated-variadic-call.
1 parent e196caa commit 9a365d8

File tree

4 files changed

+25
-31
lines changed

4 files changed

+25
-31
lines changed

cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,15 @@ class VarargsFunction extends Function {
5656
result = strictcount(FunctionCall fc | fc = this.getACallToThisFunction())
5757
}
5858

59-
string normalTerminator(int cnt) {
59+
string normalTerminator(int cnt, int totalCount) {
60+
// the terminator is 0 or -1
6061
result = ["0", "-1"] and
61-
cnt = this.trailingArgValueCount(result) and
62-
2 * cnt > this.totalCount() and
63-
not exists(FunctionCall fc, int index |
64-
// terminator value is used in a non-terminating position
65-
this.nonTrailingVarArgValue(fc, index) = result
66-
)
62+
// at least 80% of calls have the terminator
63+
cnt = trailingArgValueCount(result) and
64+
totalCount = totalCount() and
65+
100 * cnt / totalCount >= 80 and
66+
// terminator value is not used in a non-terminating position
67+
not exists(FunctionCall fc, int index | nonTrailingVarArgValue(fc, index) = result)
6768
}
6869

6970
predicate isWhitelisted() {
@@ -73,12 +74,12 @@ class VarargsFunction extends Function {
7374
}
7475
}
7576

76-
from VarargsFunction f, FunctionCall fc, string terminator, int cnt
77+
from VarargsFunction f, FunctionCall fc, string terminator, int cnt, int totalCount
7778
where
78-
terminator = f.normalTerminator(cnt) and
79+
terminator = f.normalTerminator(cnt, totalCount) and
7980
fc = f.getACallToThisFunction() and
8081
not normalisedExprValue(f.trailingArgumentIn(fc)) = terminator and
8182
not f.isWhitelisted()
8283
select fc,
83-
"Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " calls do).", f,
84-
f.getQualifiedName()
84+
"Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " of " +
85+
totalCount + " calls do).", f, f.getQualifiedName()
Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
1-
| more_tests.cpp:23:2:23:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (4 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 |
2-
| more_tests.cpp:34:2:34:12 | call to myFunction4 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:7:6:7:16 | myFunction4 | myFunction4 |
3-
| more_tests.cpp:44:2:44:12 | call to myFunction6 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:9:6:9:16 | myFunction6 | myFunction6 |
4-
| more_tests.cpp:55:2:55:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 |
5-
| more_tests.cpp:56:2:56:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 |
6-
| tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 calls do). | tests.c:4:6:4:7 | f1 | f1 |
7-
| tests.c:67:2:67:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 |
8-
| tests.c:68:2:68:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 |
9-
| tests.c:73:2:73:3 | call to f7 | Calls to $@ should use the value 0 as a terminator (3 calls do). | tests.c:28:6:28:7 | f7 | f7 |
1+
| more_tests.cpp:23:2:23:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (4 of 5 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 |
2+
| tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 of 5 calls do). | tests.c:4:6:4:7 | f1 | f1 |

cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/more_tests.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,35 @@ int main()
1313
{
1414
int x;
1515

16-
myFunction1("%i", 0); // not common enough to be assumed a terminator
16+
myFunction1("%i", 0); // GOOD: not common enough to be assumed a terminator
1717
myFunction1("%i", x);
1818

1919
myFunction2(-1);
2020
myFunction2(0, -1);
2121
myFunction2(0, 1, -1);
2222
myFunction2(0, 1, 2, -1);
23-
myFunction2(0, 1, 2, 3); // missing terminator
23+
myFunction2(0, 1, 2, 3); // BAD: missing terminator [NOT DETECTED]
2424

2525
myFunction3(-1);
2626
myFunction3(0, -1);
27-
myFunction3(-1, 1, -1); // -1 isn't a terminator because it's used in a non-terminal position
27+
myFunction3(-1, 1, -1); // GOOD: -1 isn't a terminator because it's used in a non-terminal position
2828
myFunction3(0, 1, 2, -1);
2929
myFunction3(0, 1, 2, 3);
3030

3131
myFunction4(x, x, 0);
3232
myFunction4(0, x, 1, 0);
3333
myFunction4(0, 0, 1, 1, 0);
34-
myFunction4(x, 0, 1, 1, 1); // missing terminator
34+
myFunction4(x, 0, 1, 1, 1); // BAD: missing terminator [NOT DETECTED]
3535

36-
myFunction5('a', 'b', 'c', 0); // ambiguous terminator
36+
myFunction5('a', 'b', 'c', 0); // GOOD: ambiguous terminator
3737
myFunction5('a', 'b', 'c', 0);
3838
myFunction5('a', 'b', 'c', 0);
3939
myFunction5('a', 'b', 'c', -1);
4040
myFunction5('a', 'b', 'c', -1);
4141
myFunction5('a', 'b', 'c', -1);
4242

4343
myFunction6(0.0);
44-
myFunction6(1.0); // missing terminator
44+
myFunction6(1.0); // BAD: missing terminator [NOT DETECTED]
4545
myFunction6(1.0, 2.0, 0.0);
4646
myFunction6(1.0, 2.0, 3.0, 0.0);
4747

@@ -52,8 +52,8 @@ int main()
5252
myFunction7("one", "two", "three", 0);
5353
myFunction7("alpha", "beta", "gamma", 0);
5454
myFunction7("", 0);
55-
myFunction7("yes", "no"); // missing terminator
56-
myFunction7(); // missing terminator
55+
myFunction7("yes", "no"); // BAD: missing terminator [NOT DETECTED]
56+
myFunction7(); // BAD: missing terminator [NOT DETECTED]
5757

5858
return 0;
5959
}

cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/tests.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ int main(int argc, char *argv[])
6464
f6("fsdf", 3, 8, -1);
6565
f6("a", 7, 9, 10, -1);
6666
f6("a", 1, 22, 6, 17, 2, -1);
67-
f6("fgasfgas", 5, 6, argc); // BAD: not (necessarily) terminated with -1
68-
f6("sadfsaf"); // BAD: not terminated with -1
67+
f6("fgasfgas", 5, 6, argc); // BAD: not (necessarily) terminated with -1 [NOT DETECTED]
68+
f6("sadfsaf"); // BAD: not terminated with -1 [NOT DETECTED]
6969

7070
f7("", 0);
7171
f7("", 0);
7272
f7("", 0);
73-
f7(""); // BAD: not terminated with 0
73+
f7(""); // BAD: not terminated with 0 [NOT DETECTED]
7474

7575
return 0;
7676
}

0 commit comments

Comments
 (0)