Skip to content

Commit a6654fc

Browse files
authored
Update ImproperCheckReturnValueScanf.ql
1 parent e9fefab commit a6654fc

File tree

1 file changed

+52
-53
lines changed

1 file changed

+52
-53
lines changed

cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.ql

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,92 +13,91 @@
1313

1414
import cpp
1515
import semmle.code.cpp.commons.Exclusions
16-
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1716

1817
/** Returns the position of the first argument being filled. */
1918
int posArgumentInFunctionCall(FunctionCall fc) {
2019
(
21-
(
22-
fc.getTarget().hasGlobalOrStdName(["scanf", "scanf_s"])
23-
) and
20+
fc.getTarget().hasGlobalOrStdName(["scanf", "scanf_s"]) and
2421
result = 1
2522
or
26-
(
27-
fc.getTarget().hasGlobalOrStdName(["fscanf", "sscanf", "fscanf_s", "sscanf_s"])
28-
) and
23+
fc.getTarget().hasGlobalOrStdName(["fscanf", "sscanf", "fscanf_s", "sscanf_s"]) and
2924
result = 2
3025
)
3126
}
3227

33-
from FunctionCall fc, int n
34-
where
35-
n = posArgumentInFunctionCall(fc) and
36-
// Function return value is not evaluated.
37-
fc instanceof ExprInVoidContext and
38-
not isFromMacroDefinition(fc) and
39-
exists(Expr e0, int i |
40-
i in [n .. fc.getNumberOfArguments() - 1] and
28+
/** Holds if a function argument was not initialized but used after the call. */
29+
predicate argumentIsNotInitializedAndIsUsed(Variable vt, FunctionCall fc) {
30+
exists(Expr e0 |
4131
// Fillable argument was not initialized.
32+
vt instanceof LocalScopeVariable and
33+
not vt.getAnAssignment().getASuccessor+() = fc and
4234
(
43-
fc.getArgument(i).(VariableAccess).getTarget() instanceof LocalScopeVariable or
44-
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() instanceof
45-
LocalScopeVariable
35+
not vt.hasInitializer()
36+
or
37+
exists(Expr e1, Variable v1 |
38+
e1 = vt.getInitializer().getExpr() and
39+
v1 = e1.(AddressOfExpr).getOperand().(VariableAccess).getTarget() and
40+
(
41+
not v1.hasInitializer() and
42+
not v1.getAnAssignment().getASuccessor+() = fc
43+
)
44+
)
4645
) and
47-
(
48-
not fc.getArgument(i).(VariableAccess).getTarget().hasInitializer() and
49-
not fc.getArgument(i)
50-
.(AddressOfExpr)
51-
.getOperand()
52-
.(VariableAccess)
53-
.getTarget()
54-
.hasInitializer()
46+
not exists(AssignExpr ae |
47+
ae.getLValue() = vt.getAnAccess().getParent() and
48+
ae.getASuccessor+() = fc
5549
) and
56-
(
57-
not fc.getArgument(i).(VariableAccess).getTarget().getAnAssignment().getASuccessor+() = fc and
58-
not fc.getArgument(i)
59-
.(AddressOfExpr)
60-
.getOperand()
61-
.(VariableAccess)
62-
.getTarget()
63-
.getAnAssignment()
64-
.getASuccessor+() = fc
50+
not exists(FunctionCall f0 |
51+
f0.getAnArgument().getAChild() = vt.getAnAccess() and
52+
f0.getASuccessor+() = fc
6553
) and
6654
// After the call, the completed arguments are assigned or returned as the result of the operation of the upper function.
6755
fc.getASuccessor+() = e0 and
6856
(
6957
(
70-
e0.(Assignment).getRValue().(VariableAccess).getTarget() =
71-
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
72-
e0.(Assignment).getRValue().(VariableAccess).getTarget() =
73-
fc.getArgument(i).(VariableAccess).getTarget()
58+
e0.(Assignment).getRValue().(VariableAccess).getTarget() = vt or
59+
e0.(Assignment).getRValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = vt
7460
)
7561
or
7662
e0.getEnclosingStmt() instanceof ReturnStmt and
77-
(
78-
e0.(VariableAccess).getTarget() =
79-
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
80-
e0.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget()
81-
)
63+
e0.(VariableAccess).getTarget() = vt
8264
or
8365
not exists(Expr e1 |
8466
fc.getASuccessor+() = e1 and
85-
(
86-
e1.(VariableAccess).getTarget() =
87-
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
88-
e1.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget()
89-
)
67+
e1.(VariableAccess).getTarget() = vt
9068
)
9169
)
70+
)
71+
}
72+
73+
from FunctionCall fc, int i
74+
where
75+
// Function return value is not evaluated.
76+
fc instanceof ExprInVoidContext and
77+
not isFromMacroDefinition(fc) and
78+
i in [posArgumentInFunctionCall(fc) .. fc.getNumberOfArguments() - 1] and
79+
(
80+
argumentIsNotInitializedAndIsUsed(fc.getArgument(i).(VariableAccess).getTarget(), fc) or
81+
argumentIsNotInitializedAndIsUsed(fc.getArgument(i)
82+
.(AddressOfExpr)
83+
.getOperand()
84+
.(VariableAccess)
85+
.getTarget(), fc) or
86+
argumentIsNotInitializedAndIsUsed(fc.getArgument(i)
87+
.(ArrayExpr)
88+
.getArrayBase()
89+
.(VariableAccess)
90+
.getTarget(), fc)
9291
) and
9392
// After the call, filled arguments are not evaluated.
94-
not exists(Expr e0, int i |
95-
i in [n .. fc.getNumberOfArguments() - 1] and
93+
not exists(Expr e0, int i1 |
94+
i1 in [posArgumentInFunctionCall(fc) .. fc.getNumberOfArguments() - 1] and
9695
fc.getASuccessor+() = e0 and
9796
e0.getEnclosingElement() instanceof ComparisonOperation and
9897
(
99-
e0.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget() or
98+
e0.(VariableAccess).getTarget() = fc.getArgument(i1).(VariableAccess).getTarget() or
10099
e0.(VariableAccess).getTarget() =
101-
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget()
100+
fc.getArgument(i1).(AddressOfExpr).getOperand().(VariableAccess).getTarget()
102101
)
103102
)
104103
select fc, "Unchecked return value for call to '" + fc.getTarget().getName() + "'."

0 commit comments

Comments
 (0)