Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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
bgColor#FFCCCC
#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
bgColor#ccccff
#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
bgColor#ffcccc
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
bgColor#ccccff
/* ... */
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
bgColor#ffcccc

#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
bgColor#ccccff

#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"