Skip to content

Commit c507b33

Browse files
authored
Merge pull request #3921 from catenacyber/NullCheckParam
C++: Adds another redundant null check rule
2 parents e7322d1 + 07610e0 commit c507b33

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
void test(char *arg1, int *arg2) {
2+
if (arg1[0] == 'A') {
3+
if (arg2 != NULL) { //maybe redundant
4+
*arg2 = 42;
5+
}
6+
}
7+
if (arg1[1] == 'B')
8+
{
9+
*arg2 = 54; //dereferenced without checking first
10+
}
11+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>This rule finds comparisons of a function parameter to null that occur when in another path the parameter is dereferenced without a guard check. It's
8+
likely either the check is not required and can be removed, or it should be added before the dereference
9+
so that a null pointer dereference does not occur.</p>
10+
</overview>
11+
12+
<recommendation>
13+
<p>A check should be added to before the dereference, in a way that prevents a null pointer value from
14+
being dereferenced. If it's clear that the pointer cannot be null, consider removing the check instead.</p>
15+
</recommendation>
16+
17+
<example>
18+
<sample src="RedundantNullCheckParam.cpp" />
19+
</example>
20+
21+
<references>
22+
<li>
23+
<a href="https://www.owasp.org/index.php/Null_Dereference">
24+
Null Dereference
25+
</a>
26+
</li>
27+
</references>
28+
29+
</qhelp>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @name Redundant null check or missing null check of parameter
3+
* @description Checking a parameter for nullness in one path,
4+
* and not in another is likely to be a sign that either
5+
* the check can be removed, or added in the other case.
6+
* @kind problem
7+
* @id cpp/redundant-null-check-param
8+
* @problem.severity recommendation
9+
* @tags reliability
10+
* security
11+
* external/cwe/cwe-476
12+
*/
13+
14+
import cpp
15+
16+
predicate blockDominates(Block check, Block access) {
17+
check.getLocation().getStartLine() <= access.getLocation().getStartLine() and
18+
check.getLocation().getEndLine() >= access.getLocation().getEndLine()
19+
}
20+
21+
predicate isCheckedInstruction(VariableAccess unchecked, VariableAccess checked) {
22+
checked = any(VariableAccess va | va.getTarget() = unchecked.getTarget()) and
23+
//Simple test if the first access in this code path is dereferenced
24+
not dereferenced(checked) and
25+
blockDominates(checked.getEnclosingBlock(), unchecked.getEnclosingBlock())
26+
}
27+
28+
predicate candidateResultUnchecked(VariableAccess unchecked) {
29+
not isCheckedInstruction(unchecked, _)
30+
}
31+
32+
predicate candidateResultChecked(VariableAccess check, EqualityOperation eqop) {
33+
//not dereferenced to check against pointer, not its pointed value
34+
not dereferenced(check) and
35+
//assert macros are not taken into account
36+
not check.isInMacroExpansion() and
37+
// is part of a comparison against some constant NULL
38+
eqop.getAnOperand() = check and
39+
eqop.getAnOperand() instanceof NullValue
40+
}
41+
42+
from VariableAccess unchecked, VariableAccess check, EqualityOperation eqop, Parameter param
43+
where
44+
// a dereference
45+
dereferenced(unchecked) and
46+
// for a function parameter
47+
unchecked.getTarget() = param and
48+
// this function parameter is not overwritten
49+
count(param.getAnAssignment()) = 0 and
50+
check.getTarget() = param and
51+
// which is once checked
52+
candidateResultChecked(check, eqop) and
53+
// and which has not been checked before in this code path
54+
candidateResultUnchecked(unchecked)
55+
select check, "This null check is redundant or there is a missing null check before $@ ", unchecked,
56+
"where dereferencing happens"

0 commit comments

Comments
 (0)