...
The C Standard identifies five two distinct situations in which undefined behavior (UB) may arise as a result of invoking a function using a declaration that is incompatible with its definition or by supplying incorrect types or numbers of arguments:
UB | Description |
A pointer is used to call a function whose type is not compatible with the referenced type (6.3.2.3). |
For a call to a function without a function prototype in scope, the number of arguments does not equal the number of parameters (6.5.2.2).
For a call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2).
A function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function (6.5.2.2). |
Functions that are appropriately declared (as in DCL40-C. Do not create incompatible declarations of the same function or object) will typically generate a compiler diagnostic message if they are supplied with the wrong number or types of arguments. However, there are cases in which supplying the incorrect arguments to a function will, at best, generate compiler warnings. Although such warnings should be resolved, they do not prevent program compilation. (See MSC00-C. Compile cleanly at high warning levels.)
...
Functions That Should Not Be Called with Complex Values
atan2() | erf | fdim | fmin | ilogb | llround | logb | nextafter | rint | tgamma |
cbrt | erfc | floor | fmod | ldexp | log10 | lrint | nexttoward | round | trunc |
ceil | exp2 | fma | frexp | lgamma | log1p | lround | remainder | scalbn |
copysign | expm1 | fmax | hypot | llrint | log2 | nearbyint | remquo | scalbln |
This noncompliant code example attempts to take the base-2 logarithm of a complex number, resulting in undefined behavior:
...
In this noncompliant example, the C standard library function strchr()
is called through the function pointer fp
declared with a prototype with incorrectly typed arguments. According to the C Standard, 6.3.2.3, paragraph 8 [ISO/IEC 9899:20112024],
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced the referenced type, the behavior is undefined.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <string.h> char *(*fp)(); int main(void) { const char *c; fp = strchr; c = fp('e', "Hello"); printf("%s\n", c); return 0; } |
...
The open()
function accepts a third argument to determine a newly created file's access mode. If open()
is used to create a new file , and the third argument is omitted, the file may be created with unintended access permissions. (see See FIO06-C. Create files with appropriate access permissions.).
In this noncompliant code example from a vulnerability in the useradd()
function of the shadow-utils
package CVE-2006-1174, the third argument to open()
is accidentally omitted:
Code Block | ||||
---|---|---|---|---|
| ||||
fd = open(ms, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC); |
Note that, technicallyTechnically, it is incorrect to pass a third argument to open() when not creating a new file (that is, with the O_CREAT flag not set).
Compliant Solution (POSIX)
...
Calling a function with incorrect arguments can result in unexpected or unintended program behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP37-C | Medium | Probable | High | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| incompatible-argument-type parameter-match parameter-match-computed parameter-match-type | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-EXP37 | |||||||
CodeSonar |
| LANG.FUNCS.APM | Array parameter mismatch | ||||||
Compass/ROSE |
Can detect some violations of this rule. In particular, it ensures that all calls to | |||||||||
Coverity |
| MISRA C 2012 Rule 8.2 MISRA C 2012 Rule 17.3 | Implemented Relies on functions declared with prototypes, allow compiler to check | ||||||
Cppcheck Premium |
| premium-cert-exp37-c | Fully implemented | ||||||
| CC2.EXP37 | Partially implemented | |||||||
EDG |
GCC |
|
Can detect violation of this rule when the | |||||||||
Helix QAC |
| C1331, C1332, C1333, C3002, C3320, C3335 C++0403 | |||||||
Klocwork |
| MISRA.FUNC.UNMATCHED.PARAMS | |||||||
LDRA tool suite |
| 41 D |
, 21 S, 98 S |
, 170 S |
, 496 S |
, 576 S | Partially implemented |
Parasoft C/C++test |
| CERT_C-EXP37-a | Conversions shall not be performed between non compatible pointer to a function types | ||||||
Polyspace Bug Finder |
| Checks for:
Rule partially covered. | |||||||
PVS-Studio |
| V540, V541, V549, V575, V632, V639, V666, V671, V742, V743, V764, V1004 | |||||||
SonarQube C/C++ Plugin |
| S930 | Detects incorrect argument count | ||||||
RuleChecker |
| parameter-match parameter-match-type | Partially checked | ||||||
TrustInSoft Analyzer |
| unclassified ("function type matches") | Partially verified (see one compliant and one non-compliant example). |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
CERT C Secure Coding Standard | DCL07-C. Include the appropriate type information in function declarators | Prior to 2018-01-12: CERT: Unspecified Relationship |
CERT C Secure Coding Standard | MSC00-C. Compile cleanly at high warning levels | Prior to 2018-01-12: CERT: Unspecified Relationship |
CERT C Secure Coding Standard | FIO06-C. Create files with appropriate access permissions |
Prior to 2018-01-12: CERT: Unspecified Relationship | ||
ISO/IEC TR 24772:2013 | Subprogram Signature Mismatch [OTR] | Prior to 2018-01-12: CERT: Unspecified Relationship |
ISO/IEC TS 17961 | Calling functions with incorrect arguments [argcomp] | Prior to 2018-01-12: CERT: Unspecified Relationship |
MISRA C:2012 | Rule 8.2 (required) | Prior to 2018-01-12: CERT: Unspecified Relationship |
MISRA C:2012 | Rule 17.3 (mandatory) |
Prior to 2018-01-12: CERT: Unspecified Relationship | ||
CWE 2.11 | CWE-628, Function Call with Incorrectly Specified Arguments | 2017-07-05: CERT: Rule subset of CWE |
CERT-CWE Mapping Notes
Key here for mapping notes
CWE-685 and EXP37-C
EXP37-C = Union( CWE-685, CWE-686) Intersection( CWE-685, CWE-686) = Ø
CWE-686 and EXP37-C
Intersection( EXP37-C, FIO47-C) =
- Invalid argument types passed to format I/O function
EXP37-C – FIO47-C =
- Invalid argument types passed to non-format I/O function
FIO47-C – EXP37-C =
- Invalid format string, but correctly matches arguments in number and type
EXP37-C = Union( CWE-685, CWE-686)
Intersection( CWE-685, CWE-686
...
) = Ø
CWE-628 and EXP37-C
CWE-628 = Union( EXP37-C, list) where list =
- Improper ordering of function arguments (that does not violate argument types)
- Wrong argument values or references
Bibliography
[CVE] | CVE-2006-1174 |
[ISO/IEC 9899:2011] | 6. |
5.2. |
2, " |
Function Calls" | |
[ISO/IEC 9899:2024] | 6. |
3.2. |
3, " |
Pointers" | |
[IEEE Std 1003.1:2013] | open() |
[Spinellis 2006] | Section 2.6.1, "Incorrect Routine or Arguments" |
...
...