mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
[CPP-340] Create three QL queries: (1) mismatched argument types,
(2) too few arguments and (3) too many arguments.
Create new 'UnderspecifiedFunction' folders for both queries and tests.
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
void no_argument();
|
||||
|
||||
void one_argument(int x);
|
||||
|
||||
void calls() {
|
||||
no_argument(1) // BAD: `no_argument` will accept and ignore the argument
|
||||
|
||||
one_argument(1); // GOOD: `one_argument` will accept and use the argument
|
||||
|
||||
no_argument(); // GOOD: `no_argument` has not been passed an argument
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>A function is called with arguments despite having been <i>declared</i> with an empty parameter list.
|
||||
In addition, we were either unable to find a <i>definition</i> of the function, or found one with
|
||||
an incompatible number of parameters.</p>
|
||||
|
||||
<p>This may indicate that an incorrect function is being called, or that the signature (parameter list)
|
||||
of the called function is not known to the author.</p>
|
||||
|
||||
<p>In C, a function declared with an empty parameter list <code>()</code> is considered to have an unknown
|
||||
parameter list, and therefore can be called with any set of arguments. To declare a function
|
||||
which takes no arguments, you must use <code>(void)</code> as the parameter list in any forward declarations.
|
||||
In C++, <code>()</code> means the same as <code>(void)</code>, i.e., indicates that the function accepts no
|
||||
arguments.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function without arguments, or call a different function that expects the arguments
|
||||
being passed. If possible, change the forward declaration of the <code>()</code>-function to reflect the
|
||||
arguments being passed, or change the <code>()</code> to <code>(void)</code> to indicate that no arguments
|
||||
shall be passed.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="FutileParams.c" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C++ Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments"> DCL20-C. Explicitly specify void when a function accepts no arguments </a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @name Non-empty call to function declared without parameters
|
||||
* @description A call to a function declared without parameters has arguments, which may indicate
|
||||
* that the code does not follow the author's intent.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision very-high
|
||||
* @id cpp/futile-params
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from FunctionCall fc, Function f
|
||||
where f = fc.getTarget() and not f.isVarargs()
|
||||
/* There must be a zero-parameter declaration */
|
||||
and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() = 0)
|
||||
/* There must be a mismatch between number of call arguments and number of parameters in some
|
||||
* declaration of Function f
|
||||
*/
|
||||
and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() != fc.getNumberOfArguments())
|
||||
/* There must be no actual declaration of Function f whose number of parameters matches number of call arguments */
|
||||
and not exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit() and fde.getNumberOfParameters() = fc.getNumberOfArguments())
|
||||
select fc, "This call has arguments, but $@ is not declared with any parameters.", f, f.toString()
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
void no_argument();
|
||||
|
||||
void three_arguments(int x, int y, int z);
|
||||
|
||||
void calls() {
|
||||
three_arguments(1, 2, 3); // GOOD
|
||||
three_arguments(1.0f, 2, 3.0f); // BAD: arguments 1 and 3 do not match parameters
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>A function is called with at least one argument whose type is incompatible with the type of
|
||||
the corresponding parameter of the function being called. This may cause the called function
|
||||
to behave unpredictably.</p>
|
||||
|
||||
<p>This may indicate that an incorrect function is being called, or that the
|
||||
signature (parameter list and parameter types) of the called function
|
||||
is not known to the author.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function with the proper argument types. In some cases, it may
|
||||
suffice to provide an explicit cast of an argument to the desired (parameter) type.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="MistypedFunctionArguments.c" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C++ Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments"> DCL20-C. Explicitly specify void when a function accepts no arguments </a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @name Call to a function with one or more incompatible arguments
|
||||
* @description A call to a function with at least one argument whose type does
|
||||
* not match the type of the corresponding function parameter. This may indicate
|
||||
* that the author is not familiar with the function being called. Passing mistyped
|
||||
* arguments on a stack may lead to unpredictable function behavior.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision very-high
|
||||
* @id cpp/mistyped-function-arguments
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from FunctionCall fc, Function f, Parameter p
|
||||
where
|
||||
f = fc.getTarget() and
|
||||
p = f.getAParameter() and
|
||||
not f.isVarargs() and
|
||||
p.getIndex() < fc.getNumberOfArguments() and
|
||||
// There must be a zero-parameter declaration
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
fde.getNumberOfParameters() = 0
|
||||
) and
|
||||
// Parameter p and its corresponding call argument must have mismatched types
|
||||
p.getType() != fc.getArgument(p.getIndex()).getType()
|
||||
select fc, "Calling $@: $@ is incompatible with $@.", f, f.toString(), fc.getArgument(p.getIndex()),
|
||||
fc.getArgument(p.getIndex()).toString(), p, p.getTypedName()
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
void one_argument(int x);
|
||||
|
||||
void calls() {
|
||||
one_argument(1); // GOOD: `one_argument` will accept and use the argument
|
||||
|
||||
one_argument(); // BAD: `one_argument` will receive an undefined value
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>A function is called with fewer arguments than there are parameters of the function.</p>
|
||||
|
||||
<p>This may indicate that an incorrect function is being called, or that the signature
|
||||
(parameter list) of the called function is not known to the author.</p>
|
||||
|
||||
<p>In C, function calls generally need to provide the same number of arguments as there are
|
||||
arguments to the function. (Variadic functions can accept additional arguments.) Providing
|
||||
fewer arguments than there are parameters is extremely dangerous, as the called function
|
||||
will nevertheless try to obtain the missing arguments' values, either from the stack
|
||||
or from machine registers. As a result, the function may behave unpredictably.</p>
|
||||
|
||||
<p>If the called function <i>modifies</i> a parameter corresponding to a missing argument, it
|
||||
may alter the state of the program upon its return. An attacker could use this to,
|
||||
for example, alter the control flow of the program to access forbidden resources.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function with the correct number of arguments.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="TooFewArguments.c" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C++ Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments"> DCL20-C. Explicitly specify void when a function accepts no arguments </a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @name Call to function with fewer arguments than declared parameters
|
||||
* @description A function call passed fewer arguments than the number of
|
||||
* declared parameters of the function. This may indicate
|
||||
* that the code does not follow the author's intent. It is also a vulnerability,
|
||||
* since the function is like to operate on undefined data.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @precision very-high
|
||||
* @id cpp/too-few-arguments
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from FunctionCall fc, Function f
|
||||
where
|
||||
f = fc.getTarget() and
|
||||
not f.isVarargs() and
|
||||
// There must be a zero-parameter declaration (explicit or implicit)
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
fde.getNumberOfParameters() = 0
|
||||
) and
|
||||
// There is an explicit declaration of the function whose parameter count is larger
|
||||
// than the number of call arguments
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
|
||||
)
|
||||
select fc, "This call has fewer arguments than required by $@.", f, f.toString()
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
void one_argument(int x);
|
||||
|
||||
void calls() {
|
||||
|
||||
one_argument(1); // GOOD: `one_argument` will accept and use the argument
|
||||
|
||||
one_argument(1, 2); // BAD: `one_argument` will use the first argument but ignore the second
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>A function is called with more arguments than there are parameters of the function.</p>
|
||||
|
||||
<p>This may indicate that an incorrect function is being called, or that the signature
|
||||
(parameter list) of the called function is not known to the author.</p>
|
||||
|
||||
<p>In C, function calls generally need to provide the same number of arguments as there are
|
||||
arguments to the function. (Variadic functions can accept additional arguments.) Providing
|
||||
more arguments than there are parameters incurs an unneeded computational overhead, both
|
||||
in terms of time and of additional stack space.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function with the correct number of arguments.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="TooManyArguments.c" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C++ Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments"> DCL20-C. Explicitly specify void when a function accepts no arguments </a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @name Call to function with extraneous parameters
|
||||
* @description A function call to a function passed more arguments than there are
|
||||
* declared parameters of the function. This may indicate
|
||||
* that the code does not follow the author's intent.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision very-high
|
||||
* @id cpp/too-many-arguments
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from FunctionCall fc, Function f
|
||||
where
|
||||
f = fc.getTarget() and
|
||||
not f.isVarargs() and
|
||||
// There must be a zero-parameter declaration (explicit or implicit)
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
fde.getNumberOfParameters() = 0
|
||||
) and
|
||||
// There must not exist a declaration with the number of parameters
|
||||
// at least as large as the number of call arguments
|
||||
not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
fde.getNumberOfParameters() >= fc.getNumberOfArguments()
|
||||
)
|
||||
select fc, "This call has more arguments than required by $@.", f, f.toString()
|
||||
Reference in New Issue
Block a user