Wiki Markup |
---|
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 \[[DCL07-A. 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 onlybest generate compiler warnings. These warnings should be resolved \[[MSC00-A. Compile cleanly at high warning levels]\], but do not prevent program compilation. |
Non-Compliant Code Example: (function pointers)
In this example, the function pointer fp
is used to refer to the function strchr()
. However, fp
is defined without the appropriate parameter list. declared without a function prototype. As a result there is no type checking performed on the call to fp(12,2);
.
Code Block | ||
---|---|---|
| ||
#include <stdio.h> #include <string.h> char *(*fp) (); int main(void) { char *c; fp = strchr; c = fp(12, 2); printf("%s\n", c); } |
...
Compliant Solution: (function pointers)
Properly declaring fp
so it is compatible with strchr()
Declaring fp
with a function prototype corrects this example.
Code Block | ||
---|---|---|
| ||
#include <string.h> char *(*fp) (char const *, int); int main(void) { char *c; fp = strchr; c = fp("Hello",'H'); printf("%s\n", c); } |
Non-Compliant Code Example: (variadic functions)
Wiki Markup |
---|
The POSIX function {{open()}} \[[Open Group 04|AA. C References#Open Group 04]\] is a variadic function with the following prototype: |
...
Code Block | ||
---|---|---|
| ||
fd = open(ms, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC); |
Compliant Solution: (variadic functions)
To correct this example, a third argument is specified in the call to open()
.
Code Block | ||
---|---|---|
| ||
/* ... */
int fd = open(file_name, O_CREAT | O_WRONLY, file_access_permissions);
if (fd == -1){
/* Handle Error */
}
/* ... */
|
Non-Compliant Code Example (argument validation)
Using a user-defined function to calculate the amount of memory to allocate is a common practice that may sometimes be necessary. However, if the function used to calculate the size parameter is flawed, then an incorrect size argument will be supplied to the allocation routine.
This following non-compliant code reads user-supplied data from standard input, returning the number of characters read.
Code Block | ||
---|---|---|
| ||
#include <stdlib.h> #include <stdio.h> enum { MAXLINE = 1000 }; size_t calc() { char line[MAXLINE], c; size_t size = 0; while ( (c = getchar()) != EOF && c != '\n') { line[size] = c; size++; if (size >= MAXLINE) break; } return size; } int main(void) { char *line = malloc(calc()); if (line == NULL) { /* Handle malloc() error */ } /* ... */ free(line); } |
Wiki Markup |
---|
However, if no characters are entered, {{calc()}} will return {{0}}. Because there is no validation on the result of {{calc()}}, a {{malloc(0)}} \[[MEM04-A. Do not make assumptions about the result of allocating 0 bytes]\] could occur, which could lead to a buffer overflow. |
Compliant Solution (argument validation)
In this compliant solution, the result of calc()
is not supplied directly to malloc()
. Instead, the result of calc()
is stored in the variable size
and checked for the exceptional condition of being 0
. This modification reduces the complexity of the line of code that calls malloc()
and adds an additional layer of validation, thus reducing the chances of error.
Code Block | ||
---|---|---|
| ||
#include <stdlib.h>
#include <stdio.h>
enum { MAXLINE = 1000 };
size_t calc() {
char line[MAXLINE], c;
size_t size = 0;
while ( (c = getchar()) != EOF && c != '\n') {
line[size] = c;
size++;
if (size >= MAXLINE)
break;
}
return size;
}
int main(void) {
size_t size = calc();
if (!size) {
/* Handle invalid size */
}
char *line = malloc(size)
if (line == NULL) {
/* Handle malloc() error */
}
/* ... */
free(line);
}
|
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 | 1 (low) | 1 (unlikely) | 3 (low) | P3 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Forward, Section 6.9.1, "Function definitions" \[[Spinellis 06|AA. C References#Spinellis 06]\] Section 2.6.1, "Incorrect Routine or Arguments" |