Skip to content

Commit a2660e5

Browse files
authored
Merge pull request github#5326 from ihsinme/ihsinme-patch-244
CPP: Add query for CWE-20 Improper Input Validation
2 parents fc5158c + c281820 commit a2660e5

File tree

6 files changed

+111
-0
lines changed

6 files changed

+111
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
if(len<0) return 1;
2+
memset(dest, source, len); // GOOD: variable `len` checked before call
3+
4+
...
5+
6+
memset(dest, source, len); // BAD: variable `len` checked after call
7+
if(len<0) return 1;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Checking the function argument after calling the function itself. This situation looks suspicious and requires the attention of the developer. It may be necessary to add validation before calling the function</p>
7+
8+
9+
</overview>
10+
<recommendation>
11+
12+
<p>We recommend checking before calling the function.</p>
13+
14+
</recommendation>
15+
<example>
16+
<p>The following example demonstrates an erroneous and fixed use of function argument validation.</p>
17+
<sample src="LateCheckOfFunctionArgument.c" />
18+
19+
</example>
20+
<references>
21+
22+
<li>
23+
CWE Common Weakness Enumeration:
24+
<a href="https://cwe.mitre.org/data/definitions/20.html"> CWE-20: Improper Input Validation</a>.
25+
</li>
26+
27+
</references>
28+
</qhelp>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @name Late Check Of Function Argument
3+
* @description --Checking the function argument after calling the function itself.
4+
* --This situation looks suspicious and requires the attention of the developer.
5+
* --It may be necessary to add validation before calling the function.
6+
* @kind problem
7+
* @id cpp/late-check-of-function-argument
8+
* @problem.severity warning
9+
* @precision medium
10+
* @tags correctness
11+
* security
12+
* external/cwe/cwe-20
13+
*/
14+
15+
import cpp
16+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
17+
18+
/** Holds for a function `f` that has an argument at index `apos` used for positioning in a buffer. */
19+
predicate numberArgument(Function f, int apos) {
20+
f.hasGlobalOrStdName("write") and apos = 2
21+
or
22+
f.hasGlobalOrStdName("read") and apos = 2
23+
or
24+
f.hasGlobalOrStdName("lseek") and apos = 1
25+
or
26+
f.hasGlobalOrStdName("memmove") and apos = 2
27+
or
28+
f.hasGlobalOrStdName("memset") and apos = 2
29+
or
30+
f.hasGlobalOrStdName("memcpy") and apos = 2
31+
or
32+
f.hasGlobalOrStdName("memcmp") and apos = 2
33+
or
34+
f.hasGlobalOrStdName("strncat") and apos = 2
35+
or
36+
f.hasGlobalOrStdName("strncpy") and apos = 2
37+
or
38+
f.hasGlobalOrStdName("strncmp") and apos = 2
39+
or
40+
f.hasGlobalOrStdName("snprintf") and apos = 1
41+
or
42+
f.hasGlobalOrStdName("strndup") and apos = 2
43+
}
44+
45+
class IfCompareWithZero extends IfStmt {
46+
IfCompareWithZero() { this.getCondition().(RelationalOperation).getAChild().getValue() = "0" }
47+
48+
Expr noZerroOperand() {
49+
if this.getCondition().(RelationalOperation).getGreaterOperand().getValue() = "0"
50+
then result = this.getCondition().(RelationalOperation).getLesserOperand()
51+
else result = this.getCondition().(RelationalOperation).getGreaterOperand()
52+
}
53+
}
54+
55+
from FunctionCall fc, IfCompareWithZero ifc, int na
56+
where
57+
numberArgument(fc.getTarget(), na) and
58+
globalValueNumber(fc.getArgument(na)) = globalValueNumber(ifc.noZerroOperand()) and
59+
dominates(fc, ifc) and
60+
not exists(IfStmt ifc1 |
61+
dominates(ifc1, fc) and
62+
globalValueNumber(fc.getArgument(na)) = globalValueNumber(ifc1.getCondition().getAChild*())
63+
)
64+
select fc,
65+
"The value of argument '$@' appears to be checked after the call, rather than before it.",
66+
fc.getArgument(na), fc.getArgument(na).toString()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:6:3:6:8 | call to memset | The value of argument '$@' appears to be checked after the call, rather than before it. | test.c:6:17:6:20 | len1 | len1 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-020/LateCheckOfFunctionArgument.ql
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
void workFunction_0(char *s) {
2+
int len = 5, len1;
3+
char buf[80], buf1[8];
4+
if(len<0) return;
5+
memset(buf,0,len); //GOOD
6+
memset(buf1,0,len1); //BAD
7+
if(len1<0) return;
8+
}

0 commit comments

Comments
 (0)