mirror of
https://github.com/github/codeql.git
synced 2026-05-03 20:58:03 +02:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
...
|
||||
r = scanf("%i", i);
|
||||
if (r == 1) // GOOD
|
||||
return i;
|
||||
else
|
||||
return -1;
|
||||
...
|
||||
scanf("%i", i); // BAD
|
||||
return i;
|
||||
...
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Working with reading data without validation procedures and with uninitialized arguments can lead to unpredictable consequences.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates erroneous and corrected work with a function call.</p>
|
||||
<sample src="ImproperCheckReturnValueScanf.cpp" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP12-C.+Do+not+ignore+values+returned+by+functions">EXP12-C. Do not ignore values returned by functions</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @name Improper check return value scanf.
|
||||
* @description Using a function call without the ability to evaluate the correctness of the work can lead to unexpected results.
|
||||
* @kind problem
|
||||
* @id cpp/improper-check-return-value-scanf
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-754
|
||||
* external/cwe/cwe-908
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.Exclusions
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/** Returns the starting position of the argument being filled. */
|
||||
int posArgumentInFunctionCall(FunctionCall fc) {
|
||||
(
|
||||
(
|
||||
fc.getTarget().hasGlobalOrStdName("scanf") or
|
||||
fc.getTarget().hasGlobalOrStdName("scanf_s")
|
||||
) and
|
||||
result = 1
|
||||
or
|
||||
(
|
||||
fc.getTarget().hasGlobalOrStdName("fscanf") or
|
||||
fc.getTarget().hasGlobalOrStdName("sscanf") or
|
||||
fc.getTarget().hasGlobalOrStdName("fscanf_s") or
|
||||
fc.getTarget().hasGlobalOrStdName("sscanf_s")
|
||||
) and
|
||||
result = 2
|
||||
)
|
||||
}
|
||||
|
||||
from FunctionCall fc, int n
|
||||
where
|
||||
n = posArgumentInFunctionCall(fc) and
|
||||
// Function return value is not evaluated.
|
||||
fc instanceof ExprInVoidContext and
|
||||
not isFromMacroDefinition(fc) and
|
||||
exists(Expr e0, int i |
|
||||
i in [n .. fc.getNumberOfArguments() - 1] and
|
||||
// Fillable argument was not initialized.
|
||||
(
|
||||
fc.getArgument(i).(VariableAccess).getTarget() instanceof LocalScopeVariable or
|
||||
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() instanceof
|
||||
LocalScopeVariable
|
||||
) and
|
||||
(
|
||||
not fc.getArgument(i).(VariableAccess).getTarget().hasInitializer() and
|
||||
not fc.getArgument(i)
|
||||
.(AddressOfExpr)
|
||||
.getOperand()
|
||||
.(VariableAccess)
|
||||
.getTarget()
|
||||
.hasInitializer()
|
||||
) and
|
||||
(
|
||||
not fc.getArgument(i).(VariableAccess).getTarget().getAnAssignment().getASuccessor+() = fc and
|
||||
not fc.getArgument(i)
|
||||
.(AddressOfExpr)
|
||||
.getOperand()
|
||||
.(VariableAccess)
|
||||
.getTarget()
|
||||
.getAnAssignment()
|
||||
.getASuccessor+() = fc
|
||||
) and
|
||||
// After the call, the completed arguments are assigned or returned as the result of the operation of the upper function.
|
||||
fc.getASuccessor+() = e0 and
|
||||
(
|
||||
(
|
||||
e0.(Assignment).getRValue().(VariableAccess).getTarget() =
|
||||
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
|
||||
e0.(Assignment).getRValue().(VariableAccess).getTarget() =
|
||||
fc.getArgument(i).(VariableAccess).getTarget()
|
||||
)
|
||||
or
|
||||
e0.getEnclosingStmt() instanceof ReturnStmt and
|
||||
(
|
||||
e0.(VariableAccess).getTarget() =
|
||||
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
|
||||
e0.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget()
|
||||
)
|
||||
or
|
||||
not exists(Expr e1 |
|
||||
fc.getASuccessor+() = e1 and
|
||||
(
|
||||
e1.(VariableAccess).getTarget() =
|
||||
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget() or
|
||||
e1.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget()
|
||||
)
|
||||
)
|
||||
)
|
||||
) and
|
||||
// After the call, filled arguments are not evaluated.
|
||||
not exists(Expr e0, int i |
|
||||
i in [n .. fc.getNumberOfArguments() - 1] and
|
||||
fc.getASuccessor+() = e0 and
|
||||
e0.getEnclosingElement() instanceof ComparisonOperation and
|
||||
(
|
||||
e0.(VariableAccess).getTarget() = fc.getArgument(i).(VariableAccess).getTarget() or
|
||||
e0.(VariableAccess).getTarget() =
|
||||
fc.getArgument(i).(AddressOfExpr).getOperand().(VariableAccess).getTarget()
|
||||
)
|
||||
)
|
||||
select fc, "Unchecked return value for call to '" + fc.getTarget().getName() + "'."
|
||||
Reference in New Issue
Block a user