Skip to content

Commit 3ec988c

Browse files
committed
[CPP-340] Rename 'UnspecifiedFunctions' to 'Unspecified Functions'
Make MistypedFunctionArguments.ql more restrictive (allowing type matching only in the presence of no-op conversions).
1 parent 8a653b9 commit 3ec988c

19 files changed

+389
-2
lines changed

cpp/config/suites/c/correctness

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/IntMultToLong.ql: /Correctness/Dangerous Conversions
77
+ semmlecode-cpp-queries/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql: /Correctness/Dangerous Conversions
88
+ semmlecode-cpp-queries/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql: /Correctness/Dangerous Conversions
9+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions
910
+ semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions
1011
# Consistent Use
1112
+ semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use
@@ -15,7 +16,8 @@
1516
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql: /Correctness/Common Errors
1617
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql: /Correctness/Common Errors
1718
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
18-
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/FutileParams.ql: /Correctness/Common Errors
19+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
20+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
1921
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
2022
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
2123
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors

cpp/config/suites/cpp/correctness

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
+ semmlecode-cpp-queries/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql: /Correctness/Dangerous Conversions
88
+ semmlecode-cpp-queries/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql: /Correctness/Dangerous Conversions
99
+ semmlecode-cpp-queries/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql: /Correctness/Dangerous Conversions
10+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions
1011
+ semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions
1112
# Consistent Use
1213
+ semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use
@@ -16,7 +17,8 @@
1617
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql: /Correctness/Common Errors
1718
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql: /Correctness/Common Errors
1819
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
19-
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/FutileParams.ql: /Correctness/Common Errors
20+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
21+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
2022
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
2123
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
2224
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void three_arguments(int x, int y, int z);
2+
3+
void calls() {
4+
int three = 3;
5+
three_arguments(1, 2, three); // GOOD
6+
three_arguments(1, 2, &three); // BAD
7+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
7+
<overview>
8+
<p>A function is called with at least one argument whose type is incompatible with the type of
9+
the corresponding parameter of the function being called. This may cause the called function
10+
to behave unpredictably.</p>
11+
12+
<p>This may indicate that an incorrect function is being called, or that the
13+
signature (parameter list and parameter types) of the called function
14+
is not known to the author.</p>
15+
16+
</overview>
17+
<recommendation>
18+
<p>Call the function with the proper argument types. In some cases, it may
19+
suffice to provide an explicit cast of an argument to the desired (parameter) type.</p>
20+
21+
</recommendation>
22+
<example><sample src="MistypedFunctionArguments.c" />
23+
24+
</example>
25+
26+
<references>
27+
<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>
28+
</references>
29+
</qhelp>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* @name Call to a function with one or more incompatible arguments
3+
* @description A call to a function with at least one argument whose type does
4+
* not match the type of the corresponding function parameter. This may indicate
5+
* that the author is not familiar with the function being called. Passing mistyped
6+
* arguments on a stack may lead to unpredictable function behavior.
7+
* @kind problem
8+
* @problem.severity warning
9+
* @precision very-high
10+
* @id cpp/mistyped-function-arguments
11+
* @tags correctness
12+
* maintainability
13+
*/
14+
15+
import cpp
16+
17+
pragma[inline]
18+
int sizeofInt() { result = any(IntType pt).getSize() }
19+
20+
pragma[inline]
21+
predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
22+
arg = parm
23+
or
24+
// arithmetic types
25+
arg instanceof ArithmeticType and
26+
parm instanceof ArithmeticType and
27+
arg.getSize() = parm.getSize() and
28+
(
29+
(
30+
arg instanceof IntegralType and
31+
parm instanceof IntegralType
32+
)
33+
or
34+
(
35+
arg instanceof FloatingPointType and
36+
parm instanceof FloatingPointType
37+
)
38+
)
39+
or
40+
// pointers to void are ok
41+
arg instanceof VoidType
42+
or
43+
parm instanceof VoidType
44+
}
45+
46+
pragma[inline]
47+
predicate argTypeMayBeUsed(Type arg, Type parm) {
48+
arg = parm
49+
or
50+
// float will be promoted to double, and so it should correspond
51+
// to the prototype
52+
arg instanceof FloatType and parm instanceof DoubleType
53+
or
54+
// integral types are promoted "up to" (unsigned) int, but not long long.
55+
arg instanceof IntegralType and
56+
parm instanceof IntegralType and
57+
arg.getSize() <= sizeofInt() and
58+
parm.getSize() <= sizeofInt()
59+
or
60+
/*
61+
* // we allow interoperability between long long and pointer
62+
* arg.getSize() = parm.getSize() and
63+
* (
64+
* (arg instanceof IntegralType and parm instanceof PointerType)
65+
* or
66+
* (arg instanceof PointerType and parm instanceof IntegralType)
67+
* )
68+
* or
69+
*/
70+
71+
// pointers to compatible types
72+
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
73+
parm.(PointerType).getBaseType().getUnspecifiedType())
74+
or
75+
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
76+
parm.(ArrayType).getBaseType().getUnspecifiedType())
77+
or
78+
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
79+
parm.(PointerType).getBaseType().getUnspecifiedType())
80+
or
81+
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
82+
parm.(ArrayType).getBaseType().getUnspecifiedType())
83+
}
84+
85+
// This predicate doesn't necessarily have to exist, but if it does exist
86+
// then it must be inline to make sure we don't enumerate all pairs of
87+
// compatible types.
88+
// Its body could also just be hand-inlined where it's used.
89+
pragma[inline]
90+
predicate argMayBeUsed(Expr arg, Parameter parm) {
91+
argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
92+
parm.getType().getUnspecifiedType())
93+
}
94+
95+
from FunctionCall fc, Function f, Parameter p
96+
where
97+
f = fc.getTarget() and
98+
p = f.getAParameter() and
99+
not f.isVarargs() and
100+
p.getIndex() < fc.getNumberOfArguments() and
101+
// There must be a zero-parameter declaration
102+
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
103+
fde.getNumberOfParameters() = 0
104+
) and
105+
// Parameter p and its corresponding call argument must have mismatched types
106+
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
107+
select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
108+
fc.getArgument(p.getIndex()) as arg, arg.toString(), arg.getFullyConverted().getType() as type,
109+
type.toString(), p, p.getTypedName()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
void one_argument();
2+
3+
void calls() {
4+
one_argument(1); // GOOD: `one_argument` will accept and use the argument
5+
6+
one_argument(); // BAD: `one_argument` will receive an undefined value
7+
}
8+
9+
void one_argument(int x);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
7+
<overview>
8+
<p>A function is called with fewer arguments than there are parameters of the function.</p>
9+
10+
<p>This may indicate that an incorrect function is being called, or that the signature
11+
(parameter list) of the called function is not known to the author.</p>
12+
13+
<p>In C, function calls generally need to provide the same number of arguments as there are
14+
arguments to the function. (Variadic functions can accept additional arguments.) Providing
15+
fewer arguments than there are parameters is extremely dangerous, as the called function
16+
will nevertheless try to obtain the missing arguments' values, either from the stack
17+
or from machine registers. As a result, the function may behave unpredictably.</p>
18+
19+
<p>If the called function <i>modifies</i> a parameter corresponding to a missing argument, it
20+
may alter the state of the program upon its return. An attacker could use this to,
21+
for example, alter the control flow of the program to access forbidden resources.</p>
22+
23+
</overview>
24+
<recommendation>
25+
<p>Call the function with the correct number of arguments.</p>
26+
27+
</recommendation>
28+
<example><sample src="TooFewArguments.c" />
29+
30+
</example>
31+
32+
<references>
33+
<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>
34+
</references>
35+
</qhelp>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @name Call to function with fewer arguments than declared parameters
3+
* @description A function call passed fewer arguments than the number of
4+
* declared parameters of the function. This may indicate
5+
* that the code does not follow the author's intent. It is also a vulnerability,
6+
* since the function is like to operate on undefined data.
7+
* @kind problem
8+
* @problem.severity error
9+
* @precision very-high
10+
* @id cpp/too-few-params
11+
* @tags correctness
12+
* maintainability
13+
* security
14+
*/
15+
16+
import cpp
17+
18+
from FunctionCall fc, Function f
19+
where
20+
f = fc.getTarget() and
21+
not f.isVarargs() and
22+
// There must be a zero-parameter declaration (explicit or implicit)
23+
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
24+
fde.getNumberOfParameters() = 0
25+
) and
26+
// There is an explicit declaration of the function whose parameter count is larger
27+
// than the number of call arguments
28+
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
29+
not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
30+
)
31+
select fc, "This call has fewer arguments than required by $@.", f, f.toString()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
void one_argument();
2+
3+
void calls() {
4+
5+
one_argument(1); // GOOD: `one_argument` will accept and use the argument
6+
7+
one_argument(1, 2); // BAD: `one_argument` will use the first argument but ignore the second
8+
}
9+
10+
void one_argument(int x);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
7+
<overview>
8+
<p>A function is called with more arguments than there are parameters of the function.</p>
9+
10+
<p>This may indicate that an incorrect function is being called, or that the signature
11+
(parameter list) of the called function is not known to the author.</p>
12+
13+
<p>In C, function calls generally need to provide the same number of arguments as there are
14+
arguments to the function. (Variadic functions can accept additional arguments.) Providing
15+
more arguments than there are parameters incurs an unneeded computational overhead, both
16+
in terms of time and of additional stack space.</p>
17+
18+
</overview>
19+
<recommendation>
20+
<p>Call the function with the correct number of arguments.</p>
21+
22+
</recommendation>
23+
<example><sample src="TooManyArguments.c" />
24+
25+
</example>
26+
27+
<references>
28+
<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>
29+
</references>
30+
</qhelp>

0 commit comments

Comments
 (0)