Skip to content

Commit e3be205

Browse files
authored
Merge pull request #15996 from MathiasVP/missing-check-scanf-path-problem
Make `cpp/missing-check-scanf` a `path-problem` query
2 parents 0fe3072 + 96cd259 commit e3be205

File tree

3 files changed

+159
-28
lines changed

3 files changed

+159
-28
lines changed

cpp/ql/src/Critical/MissingCheckScanf.ql

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Missing return-value check for a 'scanf'-like function
33
* @description Failing to check that a call to 'scanf' actually writes to an
44
* output variable can lead to unexpected behavior at reading time.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity warning
77
* @security-severity 7.5
88
* @precision medium
@@ -20,6 +20,7 @@ import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
2020
import semmle.code.cpp.ir.IR
2121
import semmle.code.cpp.ir.ValueNumbering
2222
import ScanfChecks
23+
import ScanfToUseFlow::PathGraph
2324

2425
/**
2526
* Holds if `n` represents an uninitialized stack-allocated variable, or a
@@ -118,10 +119,13 @@ module ScanfToUseFlow = Global<ScanfToUseConfig>;
118119
* Holds if `source` is the `index`'th argument to the `scanf`-like call `call`, and `sink` is
119120
* a dataflow node that represents the expression `e`.
120121
*/
121-
predicate hasFlow(Node source, ScanfFunctionCall call, int index, Node sink, Expr e) {
122-
isSource(call, index, source, _) and
123-
ScanfToUseFlow::flow(source, sink) and
124-
isSink(sink, e)
122+
predicate flowPath(
123+
ScanfToUseFlow::PathNode source, ScanfFunctionCall call, int index, ScanfToUseFlow::PathNode sink,
124+
Expr e
125+
) {
126+
isSource(call, index, source.getNode(), _) and
127+
ScanfToUseFlow::flowPath(source, sink) and
128+
isSink(sink.getNode(), e)
125129
}
126130

127131
/**
@@ -143,9 +147,12 @@ int getMinimumGuardConstant(ScanfFunctionCall call, int index) {
143147
* Holds the access to `e` isn't guarded by a check that ensures that `call` returned
144148
* at least `minGuard`.
145149
*/
146-
predicate hasNonGuardedAccess(ScanfFunctionCall call, Expr e, int minGuard) {
150+
predicate hasNonGuardedAccess(
151+
ScanfToUseFlow::PathNode source, ScanfFunctionCall call, ScanfToUseFlow::PathNode sink, Expr e,
152+
int minGuard
153+
) {
147154
exists(int index |
148-
hasFlow(_, call, index, _, e) and
155+
flowPath(source, call, index, sink, e) and
149156
minGuard = getMinimumGuardConstant(call, index)
150157
|
151158
not exists(int value |
@@ -173,9 +180,11 @@ BasicBlock blockGuardedBy(int value, string op, ScanfFunctionCall call) {
173180
)
174181
}
175182

176-
from ScanfFunctionCall call, Expr e, int minGuard
177-
where hasNonGuardedAccess(call, e, minGuard)
178-
select e,
183+
from
184+
ScanfToUseFlow::PathNode source, ScanfToUseFlow::PathNode sink, ScanfFunctionCall call, Expr e,
185+
int minGuard
186+
where hasNonGuardedAccess(source, call, sink, e, minGuard)
187+
select e, source, sink,
179188
"This variable is read, but may not have been written. " +
180189
"It should be guarded by a check that the $@ returns at least " + minGuard + ".", call,
181190
call.toString()
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 "Missing return-value check for a 'scanf'-like function" query (`cpp/missing-check-scanf`) has been converted to a `path-problem` query.

0 commit comments

Comments
 (0)