[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:
Ziemowit Laski
2019-03-20 19:42:51 -07:00
parent 2def0ee9c1
commit 5a092d0fed
22 changed files with 232 additions and 83 deletions

View File

@@ -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
}

View File

@@ -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>

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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>

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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>

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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>

View File

@@ -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()