Skip to content

Commit f674d43

Browse files
authored
Merge pull request #329 from geoffw0/overflowdest
CPP: Improve Overflowdest.ql
2 parents 4bed86f + 7571076 commit f674d43

File tree

2 files changed

+23
-52
lines changed

2 files changed

+23
-52
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11

22
int main(int argc, char* argv[]) {
3-
char param[SIZE];
3+
char param[20];
4+
char *arg1;
45

5-
char arg1[10];
6-
char arg2[20];
6+
arg1 = argv[1];
77

88
//wrong: only uses the size of the source (argv[1]) when using strncpy
9-
strncpy(param, argv[1], strlen(arg1));
9+
strncpy(param, arg1, strlen(arg1));
1010

1111
//correct: uses the size of the destination array as well
12-
strncpy(param, argv[1], min(strlen(arg1, sizeof(param) -1)));
12+
strncpy(param, arg1, min(strlen(arg1), sizeof(param) -1));
1313
}

cpp/ql/src/Critical/OverflowDestination.ql

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,75 +5,46 @@
55
* @kind problem
66
* @id cpp/overflow-destination
77
* @problem.severity warning
8+
* @precision low
89
* @tags reliability
910
* security
1011
* external/cwe/cwe-119
1112
* external/cwe/cwe-131
1213
*/
1314
import cpp
14-
import semmle.code.cpp.pointsto.PointsTo
15+
import semmle.code.cpp.security.TaintTracking
1516

16-
predicate sourceSized(FunctionCall fc)
17+
/**
18+
* Holds if `fc` is a call to a copy operation where the size argument contains
19+
* a reference to the source argument. For example:
20+
* ```
21+
* memcpy(dest, src, sizeof(src));
22+
* ```
23+
*/
24+
predicate sourceSized(FunctionCall fc, Expr src)
1725
{
1826
exists(string name |
1927
(name = "strncpy" or name = "strncat" or name = "memcpy" or name = "memmove") and
2028
fc.getTarget().hasQualifiedName(name))
2129
and
22-
exists(Expr dest, Expr src, Expr size, Variable v |
30+
exists(Expr dest, Expr size, Variable v |
2331
fc.getArgument(0) = dest and fc.getArgument(1) = src and fc.getArgument(2) = size and
2432
src = v.getAnAccess() and size.getAChild+() = v.getAnAccess() and
33+
34+
// exception: `dest` is also referenced in the size argument
2535
not exists(Variable other |
2636
dest = other.getAnAccess() and size.getAChild+() = other.getAnAccess())
2737
and
38+
39+
// exception: `src` and `dest` are both arrays of the same type and size
2840
not exists(ArrayType srctype, ArrayType desttype |
2941
dest.getType().getUnderlyingType() = desttype and
3042
src.getType().getUnderlyingType() = srctype and
3143
desttype.getBaseType().getUnderlyingType() = srctype.getBaseType().getUnderlyingType() and
3244
desttype.getArraySize() = srctype.getArraySize()))
3345
}
3446

35-
class VulnerableArgument extends PointsToExpr
36-
{
37-
VulnerableArgument() { sourceSized(this.getParent()) }
38-
override predicate interesting() { sourceSized(this.getParent()) }
39-
}
40-
41-
predicate taintingFunction(Function f, int buf)
42-
{
43-
(f.hasQualifiedName("read") and buf = 1) or
44-
(f.hasQualifiedName("fgets") and buf = 0) or
45-
(f.hasQualifiedName("fread") and buf = 0)
46-
}
47-
48-
// Taint `argv[i]`, for all i, but also `*argv`, etc.
49-
predicate commandLineArg(Expr e)
50-
{
51-
exists(Function f, Parameter argv, VariableAccess access |
52-
f.hasQualifiedName("main") and f.getParameter(1) = argv and
53-
argv.getAnAccess() = access and access.isRValue() and
54-
pointer(access, e))
55-
}
56-
57-
predicate tainted(Expr e)
58-
{
59-
exists(FunctionCall fc, int arg |
60-
taintingFunction(fc.getTarget(), arg) and
61-
e = fc.getArgument(arg))
62-
or
63-
e.(FunctionCall).getTarget().hasQualifiedName("getenv")
64-
or
65-
commandLineArg(e)
66-
}
67-
68-
class TaintedArgument extends PointsToExpr
69-
{
70-
TaintedArgument() { tainted(this) }
71-
override predicate interesting() { tainted(this) }
72-
}
73-
74-
from FunctionCall fc, VulnerableArgument vuln, TaintedArgument tainted
75-
where sourceSized(fc)
76-
and fc.getArgument(1) = vuln
77-
and vuln.pointsTo() = tainted.pointsTo()
78-
and vuln.confidence() > 0.01
47+
from FunctionCall fc, Expr vuln, Expr taintSource
48+
where sourceSized(fc, vuln)
49+
and tainted(taintSource, vuln)
7950
select fc, "To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size."

0 commit comments

Comments
 (0)