An application programming interface (API) specifies how a function is intended to be called. Calling a function with incorrect arguments can result in unexpected or unintended program behavior. Functions that are appropriately declared (as in recommendation DCL07-C. Include the appropriate type information in function declarators) will typically fail compilation if they are supplied with the wrong number or types of arguments. However, there are cases where supplying the incorrect arguments to a function will at best generate compiler warnings. These warnings should be resolved but do not prevent program compilation.(See recommendation MSC00-C. Compile cleanly at high warning levels.)
Noncompliant Code Example (Function Pointers)
In this example, the function pointer fp
is used to refer to the function strchr()
. However, fp
is declared without a function prototype. As a result, there is no type checking performed on the call to fp(12,2);
.
#include <stdio.h> #include <string.h> char *(*fp) (); int main(void) { char *c; fp = strchr; c = fp(12, 2); printf("%s\n", c); return 0; }
Compliant Solution (Function Pointers)
Declaring fp
with a function prototype corrects this example.
#include <string.h> char *(*fp) (const char *, int); int main(void) { char *c; fp = strchr; c = fp("Hello",'H'); printf("%s\n", c); return 0; }
Noncompliant Code Example (Variadic Functions)
The POSIX function open()
[Open Group 2004] is a variadic function with the following prototype:
int open(const char *path, int oflag, ... );
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 recommendation 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()
has been accidentally omitted.
fd = open(ms, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC);
Note that technically it is also incorrect to pass a third argument to open()
when not creating a new file (that is, with the O_CREAT
flag not set). A POSIX implementation could, if it wished, return an EINVAL error in this case. However, in practice it is unlikely to cause a problem.
Compliant Solution (Variadic Functions)
To correct this example, a third argument is specified in the call to open()
.
/* ... */ fd = open(ms, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC, file_access_permissions); if (fd == -1){ /* Handle error */ } /* ... */
Risk Assessment
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 |
---|---|---|---|
GCC |
4.3.5 |
|
can detect violation of this rule when the |
Compass/ROSE |
|
|
can detect some violations of this rule. In particular, it ensures that all calls to |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
CERT C++ Secure Coding Standard: EXP37-CPP. Call variadic functions with the arguments intended by the API
ISO/IEC 9899:1999 Forward and Section 6.9.1, "Function definitions"
ISO/IEC TR 24772 "OTR Subprogram Signature Mismatch"
MISRA Rule 16.6
MITRE CWE: CWE-628, "Function Call with Incorrectly Specified Arguments"
Bibliography
[CVE] CVE-2006-1174
[Spinellis 2006] Section 2.6.1, "Incorrect Routine or Arguments"
EXP36-C. Do not convert pointers into more strictly aligned pointer types 03. Expressions (EXP) EXP38-C. Do not call offsetof() on bit-field members or invalid types