Main Content

Tainted sign change conversion

Value from an unsecure source changes sign

Description

This defect occurs when values from unsecure sources are converted, implicitly or explicitly, from signed to unsigned values.

For example, functions that use size_t as arguments implicitly convert the argument to an unsigned integer. Some functions that implicitly convert size_t are:

bcmp
memcpy
memmove
strncmp
strncpy
calloc
malloc
memalign

Risk

If you convert a small negative number to unsigned, the result is a large positive number. The large positive number can create security vulnerabilities. For example, if you use the unsigned value in:

  • Memory size routines — causes allocating memory issues.

  • String manipulation routines — causes buffer overflow.

  • Loop boundaries — causes infinite loops.

Fix

To avoid converting unsigned negative values, check that the value being converted is within an acceptable range. For example, if the value represents a size, validate that the value is not negative and less than the maximum value size.

Extend Checker

By default, Polyspace® assumes that data from external sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data that does not originate in the current scope of Polyspace analysis as tainted, use the command line option -consider-analysis-perimeter-as-trust-boundary.

Examples

expand all

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

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

void bug_taintedsignchange(void) {
    int size;
    scanf("%d",&size);
    char str[SIZE128] = "";
    if (size<SIZE128) {
        memset(str, 'c', size); //Noncompliant
    }
}

In this example, a char buffer is created and filled using memset. The size argument to memset is an input argument to the function.

The call to memset implicitly converts size to unsigned integer. If size is a large negative number, the absolute value could be too large to represent as an integer, causing a buffer overflow.

Correction — Check Value of size

One possible correction is to check if size is inside the valid range. This correction checks if size is greater than zero and less than the buffer size before calling memset.

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

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

void corrected_taintedsignchange(void) {
    int size;
    scanf("%d",&size);
    char str[SIZE128] = "";
    if (size>0 && size<SIZE128) {
        memset(str, 'c', size);  
    }
}

Result Information

Group: Tainted Data
Language: C | C++
Default: Off
Command-Line Syntax: TAINTED_SIGN_CHANGE
Impact: Medium

Version History

Introduced in R2015b