Skip to content

Commit dfbde23

Browse files
authored
Merge pull request #7627 from geoffw0/nullterm5
C++: Fix branch related FPs in cpp/improper-null-termination.
2 parents 061b9ba + 0230494 commit dfbde23

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

cpp/ql/src/Likely Bugs/Memory Management/ImproperNullTermination.ql

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ DeclStmt declWithNoInit(LocalVariable v) {
2323
not exists(v.getInitializer())
2424
}
2525

26+
/**
27+
* Control flow reachability from a buffer that is not not null terminated to a
28+
* sink that requires null termination.
29+
*/
2630
class ImproperNullTerminationReachability extends StackVariableReachabilityWithReassignment {
2731
ImproperNullTerminationReachability() { this = "ImproperNullTerminationReachability" }
2832

@@ -52,12 +56,44 @@ class ImproperNullTerminationReachability extends StackVariableReachabilityWithR
5256

5357
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
5458
exprDefinition(v, node, _) or
55-
mayAddNullTerminator(node, v.getAnAccess()) or
56-
node.(AddressOfExpr).getOperand() = v.getAnAccess() or // address taken
5759
isSinkActual(node, v) // only report first use
5860
}
5961
}
6062

61-
from ImproperNullTerminationReachability r, LocalVariable v, VariableAccess va
62-
where r.reaches(_, v, va)
63-
select va, "Variable $@ may not be null terminated.", v, v.getName()
63+
/**
64+
* Flow from a place where null termination is added, to a sink of
65+
* `ImproperNullTerminationReachability`. This was previously implemented as a
66+
* simple barrier in `ImproperNullTerminationReachability`, but there were
67+
* false positive results involving multiple paths from source to sink. We'd
68+
* prefer to report only the results we are sure of.
69+
*/
70+
class NullTerminationReachability extends StackVariableReachabilityWithReassignment {
71+
NullTerminationReachability() { this = "NullTerminationReachability" }
72+
73+
override predicate isSourceActual(ControlFlowNode node, StackVariable v) {
74+
mayAddNullTerminator(node, v.getAnAccess()) or // null termination
75+
node.(AddressOfExpr).getOperand() = v.getAnAccess() // address taken (possible null termination)
76+
}
77+
78+
override predicate isSinkActual(ControlFlowNode node, StackVariable v) {
79+
// have the same sinks as `ImproperNullTerminationReachability`.
80+
exists(ImproperNullTerminationReachability r | r.isSinkActual(node, v))
81+
}
82+
83+
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
84+
// don't look further back than the source, or further forward than the sink
85+
exists(ImproperNullTerminationReachability r | r.isSourceActual(node, v)) or
86+
exists(ImproperNullTerminationReachability r | r.isSinkActual(node, v))
87+
}
88+
}
89+
90+
from
91+
ImproperNullTerminationReachability reaches, NullTerminationReachability nullTermReaches,
92+
ControlFlowNode source, LocalVariable v, VariableAccess sink
93+
where
94+
reaches.reaches(source, v, sink) and
95+
not exists(ControlFlowNode termination |
96+
nullTermReaches.reaches(termination, _, sink) and
97+
termination != source
98+
)
99+
select sink, "Variable $@ may not be null terminated.", v, v.getName()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The "Potential improper null termination" (`cpp/improper-null-termination`) query now produces fewer false positive results around control flow branches and loops.

cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
| test.cpp:302:10:302:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:297:8:297:14 | buffer2 | buffer2 |
1919
| test.cpp:314:10:314:15 | buffer | Variable $@ may not be null terminated. | test.cpp:310:8:310:13 | buffer | buffer |
2020
| test.cpp:336:18:336:23 | buffer | Variable $@ may not be null terminated. | test.cpp:335:8:335:13 | buffer | buffer |
21-
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
22-
| test.cpp:364:11:364:16 | buffer | Variable $@ may not be null terminated. | test.cpp:359:8:359:13 | buffer | buffer |
23-
| test.cpp:392:11:392:16 | buffer | Variable $@ may not be null terminated. | test.cpp:381:8:381:13 | buffer | buffer |
24-
| test.cpp:410:11:410:16 | buffer | Variable $@ may not be null terminated. | test.cpp:397:8:397:13 | buffer | buffer |
2521
| test.cpp:421:19:421:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:419:8:419:14 | buffer2 | buffer2 |
2622
| test.cpp:448:17:448:22 | buffer | Variable $@ may not be null terminated. | test.cpp:446:8:446:13 | buffer | buffer |
2723
| test.cpp:454:18:454:23 | buffer | Variable $@ may not be null terminated. | test.cpp:452:8:452:13 | buffer | buffer |

cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ void test_strlen(bool cond1, bool cond2)
352352
if (cond1)
353353
buffer[0] = 0;
354354
if (cond1)
355-
strlen(buffer); // GOOD [FALSE POSITIVE]
355+
strlen(buffer); // GOOD
356356
}
357357

358358
{
@@ -361,7 +361,7 @@ void test_strlen(bool cond1, bool cond2)
361361
if (cond1)
362362
buffer[0] = 0;
363363
if (cond2)
364-
strlen(buffer); // BAD
364+
strlen(buffer); // BAD [NOT DETECTED]
365365
}
366366

367367
{
@@ -389,7 +389,7 @@ void test_strlen(bool cond1, bool cond2)
389389

390390
if (init != 0)
391391
{
392-
strlen(buffer); // GOOD [FALSE POSITIVE]
392+
strlen(buffer); // GOOD
393393
}
394394
}
395395

@@ -407,7 +407,7 @@ void test_strlen(bool cond1, bool cond2)
407407
{
408408
// ...
409409
} else {
410-
strlen(buffer); // GOOD [FALSE POSITIVE]
410+
strlen(buffer); // GOOD
411411
}
412412
}
413413
}

0 commit comments

Comments
 (0)