Main Content

CWE Rule 687

Function Call With Incorrectly Specified Argument Value

Since R2023b

Description

Rule Description

The software calls a function, procedure, or routine, but the caller specifies an argument that contains the wrong value, which may lead to resultant weaknesses.

Polyspace Implementation

The rule checker checks for these issues:

  • Copy of overlapping memory

  • Standard function call with incorrect arguments

  • Variable length array with non-positive size

Examples

expand all

Issue

This issue occurs when there is a memory overlap between the source and destination argument of a copy function such as memcpy or strcpy. For instance, the source and destination arguments of strcpy are pointers to different elements in the same string.

Risk

If there is memory overlap between the source and destination arguments of copy functions, according to C standards, the behavior is undefined.

Fix

Determine if the memory overlap is what you want. If so, find an alternative function. For instance:

  • If you are using memcpy to copy values from one memory location to another, use memmove instead of memcpy.

  • If you are using strcpy to copy one string to another, use memmove instead of strcpy, as follows:

    s = strlen(source);
    memmove(destination, source, s + 1);

    strlen determines the string length without the null terminator. Therefore, you must move s+1 bytes instead of s bytes.

Example — Overlapping Copy
#include <string.h>

char str[] = {"ABCDEFGH"};

void my_copy() {
    strcpy(&str[0],(const char*)&str[2]); //Noncompliant
}

In this example, because the source and destination argument are pointers to the same string str, there is memory overlap between their allowed buffers.

Issue

This issue occurs when the arguments to certain standard functions do not meet the requirements for their use in the functions.

For instance, the arguments to these functions can be invalid in the following ways.

Function TypeSituationRiskFix
String manipulation functions such as strlen and strcpyThe pointer arguments do not point to a NULL-terminated string.The behavior of the function is undefined.Pass a NULL-terminated string to string manipulation functions.
File handling functions in stdio.h such as fputc and freadThe FILE* pointer argument can have the value NULL.The behavior of the function is undefined.Test the FILE* pointer for NULL before using it as function argument.
File handling functions in unistd.h such as lseek and read The file descriptor argument can be -1.

The behavior of the function is undefined.

Most implementations of the open function return a file descriptor value of -1. In addition, they set errno to indicate that an error has occurred when opening a file.

Test the return value of the open function for -1 before using it as argument for read or lseek.

If the return value is -1, check the value of errno to see which error has occurred.

The file descriptor argument represents a closed file descriptor.The behavior of the function is undefined.Close the file descriptor only after you have completely finished using it. Alternatively, reopen the file descriptor before using it as function argument.
Directory name generation functions such as mkdtemp and mkstempsThe last six characters of the string template are not XXXXXX.The function replaces the last six characters with a string that makes the file name unique. If the last six characters are not XXXXXX, the function cannot generate a unique enough directory name.Test if the last six characters of a string are XXXXXX before using the string as function argument.
Functions related to environment variables such as getenv and setenvThe string argument is "".The behavior is implementation-defined.Test the string argument for "" before using it as getenv or setenv argument.
The string argument terminates with an equal sign, =. For instance, "C=" instead of "C".The behavior is implementation-defined.Do not terminate the string argument with =.
String handling functions such as strtok and strstr

  • strtok: The delimiter argument is "".

  • strstr: The search string argument is "".

Some implementations do not handle these edge cases.Test the string for "" before using it as function argument.

Fix

The fix depends on the root cause of the defect. See fixes in the table above and code examples with fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example — NULL Pointer Passed as strnlen Argument
#include <string.h>
#include <stdlib.h>

enum {
    SIZE10 = 10,
    SIZE20 = 20
};

int func() {
    char* s = NULL;
    return strnlen(s, SIZE20); //Noncompliant
}

In this example, a NULL pointer is passed as strnlen argument instead of a NULL-terminated string.

Before running analysis on the code, specify a GNU® compiler. See Compiler (-compiler).

Correction — Pass NULL-terminated String

Pass a NULL-terminated string as the first argument of strnlen.

#include <string.h>
#include <stdlib.h>

enum {
    SIZE10 = 10,
    SIZE20 = 20
};

int func() {
    char* s = "";
    return strnlen(s, SIZE20);
}
Issue

This issue occurs when size of a variable-length array is zero or negative.

Risk

If the size of a variable-length array is zero or negative, unexpected behavior can occur, such as stack overflow.

Fix

When you declare a variable-length array as a local variable in a function:

  • If you use a function parameter as the array size, check that the parameter is positive.

  • If you use the result of a computation on a function parameter as the array size, check that the result is positive.

You can place a test for positive value either before the function call or the array declaration in the function body.

Example — Nonpositive Array Size
int input(void);

void add_scalar(int n, int m) {
    int r=0;
    int arr[m][n]; //Noncompliant
    for (int i=0; i<m; i++) {
        for (int j=0; j<n; j++) {
            arr[i][j] = input();
            r += arr[i][j];
        }
    }
}

void main() {
    add_scalar(2,2);
    add_scalar(-1,2);
    add_scalar(2,0);
}

In this example, the second and third calls to add_scalar result in a negative and zero size of arr.

Correction — Make Array Size Positive

One possible correction is fix or remove calls that result in a nonpositive array size.

Check Information

Category: Others

Version History

Introduced in R2023b