CWE Rule 128
Description
Rule Description
Wrap around errors occur whenever a value is incremented past the maximum value for its type and therefore "wraps around" to a very small, negative, or undefined value.
Polyspace Implementation
The rule checker checks for these issues:
Integer constant overflow
Integer conversion overflow
Integer overflow
Tainted sign change conversion
Unsigned integer constant overflow
Unsigned integer conversion overflow
Unsigned integer overflow
Examples
This issue occurs in the following cases:
You assign a compile-time integer constant to a signed integer variable whose data type cannot accommodate the value.
You use an
enumvalue that cannot be accommodated by the underlying type of theenum(and the underlying type is signed). For most C compilers, the default underlying type issigned int(based on the C standard).You perform a binary operation involving two integer constants that results in an overflow, that is, a value outside the range allowed by the data type that the operation uses. A binary operation with integer constants uses the
signed intdata type (unless you use modifiers such asuorL).
An n-bit signed integer holds values in the range [-2n-1, 2n-1-1]. For instance, c is an 8-bit signed char variable that cannot hold the value 255.
signed char c = 255;This defect checker depends on the following options:
Target processor type (-target): Determines the sizes of fundamental types.Enum type definition (-enum-type-definition): Determines the underlying types of enumerations.Compiler (-compiler): Impacts the interpretation of code.
You do not see the defect in these situations:
Creation of new constants from
constvariables (for specific compilers only).Different compilers might define compile-time constants differently. In the following code,
c+1is considered a compile-time constant by GCC compilers, but not by the standard C compiler:Whether you see a violation of this check onconst int16_t c = 32767; int16_t y = c + 1;ymight depend on your compiler.Bitwise
NOToperation.Polyspace® does not raise this violation when you perform a bitwise
NOToperation.
The default behavior for constant overflows can vary between compilers and platforms. Retaining constant overflows can reduce the portability of your code.
Even if your compilers wraps around overflowing constants with a warning, the wrap-around behavior can be unintended and cause unexpected results.
Check if the constant value is what you intended. If the value is correct, use a different, possibly wider, data type for the variable.
#define MAX_UNSIGNED_CHAR 255 //Noncompliant
#define MAX_SIGNED_CHAR 127 //Noncompliant
void main() {
char c1 = MAX_UNSIGNED_CHAR;
char c2 = MAX_SIGNED_CHAR+1;
}In this example, the defect appears on the macros
because at least one use of the macro causes an overflow. To reproduce these defects, use a
Target processor type
(-target) where char is signed by default.
One possible correction is to use a different data type for the variables that overflow.
#define MAX_UNSIGNED_CHAR 255
#define MAX_SIGNED_CHAR 127
void main() {
unsigned char c1 = MAX_UNSIGNED_CHAR;
unsigned char c2 = MAX_SIGNED_CHAR+1;
}
enum {
a=0x7fffffff,
b, //Noncompliant
c=0xffffffff //Noncompliant
} MyEnumA;In this example, the enum has an underlying type int.
The int type can accommodate values in the range
[-231, 231-1]. However, the value of the
enumerator b is 0x80000000 or 231 (one more than
the previous value a). This value falls outside the allowed range of
int.
The value of c, that is 0xffffffff or 232-1,
is even larger and also causes an overflow.
To see this defect:
Specify
Compiler (-compiler)asgeneric.Specify
Source code language (-lang)asc.
const unsigned int K_ATM_Label_Ram_init_value [] = {
0x06 | ( 3 << 29) ,
0x80 | ( 9 << 29) , //Noncompliant
( 2 << 31 ) //Noncompliant
};In this example, two of the shift operations result in values that cannot be accommodated by the signed int data type. The signed int data type can accommodate values in the range [-231, 231-1]. The operation:
9 << 29results in the value 232+536870912.2 << 31results in the value 232.
Note that even though the result is assigned to an unsigned int variable,
the overflow detection uses the underlying type of the binary operation, that is,
signed int.
This issue occurs when converting an integer to a smaller integer type. If the variable does not have enough bytes to represent the original value, the conversion overflows.
The exact storage allocation for different floating point types depends on your
processor. See Target processor type (-target).
Integer conversion overflows result in undefined behavior.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the conversion so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling.
In general, avoid conversions to smaller integer types.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
char convert(void) {
int num = 1000000;
return (char)num; //Noncompliant
}In the return statement, the integer variable num is
converted to a char. However, an 8-bit or 16-bit
character cannot represent 1000000 because it requires at least 20
bits. So the conversion operation overflows.
One possible correction is to convert to a different integer type that can represent the entire number.
long convert(void) {
int num = 1000000;
return (long)num;
}This issue occurs when an operation on integer variables results in values that cannot be represented by the data type that the operation uses. This data type depends on the operand types and determines the number of bytes allocated for storing the result, thus constraining the range of allowed values.
Note that:
The data type used to determine an overflow is based on the operand data types. If you then assign the result of an operation to another variable, a different checker,
Integer conversion overflow, determines if the value assigned also overflows the variable assigned to. For instance, in an operation such as:This checker checks for an overflow based on the types ofres = x + y;xandy, and not on the type ofres. The checker for integer conversion overflows then checks for an overflow based on the type ofres.The two operands in a binary operation might undergo promotion before the operation occurs. See also Code Prover Assumptions About Implicit Data Type Conversions (Polyspace Code Prover).
The exact storage allocation for different data types depends on your processor. See
Target processor type (-target).
Integer overflows on signed integers result in undefined behavior.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the operation so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling.
To avoid overflows in general, try one of these techniques:
Keep integer variable values restricted to within half the range of signed integers.
In operations that might overflow, check for conditions that can lead to the overflow and implement wrap around or saturation behavior depending on how the result of the operation is used. The result then becomes predictable and can be safely used in subsequent computations.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <limits.h>
int plusplus(void) {
int var = INT_MAX;
var++; //Noncompliant
return var;
}In the third statement of this function, the
variable var is increased by one. But the value
of var is the maximum integer value, so an int cannot
represent one plus the maximum integer value.
One possible correction is to change data types.
Store the result of the operation in a larger data type (Note that
on a 32-bit machine, int and long has
the same size). In this example, on a 32-bit machine, by returning
a long long instead of an int,
the overflow error is fixed.
#include <limits.h>
long long plusplus(void) {
long long lvar = INT_MAX;
lvar++;
return lvar;
}This issue 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
memalignIf 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.
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.
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.
#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.
sizeOne 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);
}
}This issue occurs in the following cases:
You assign a compile-time constant to an unsigned integer variable whose data type cannot accommodate the value.
You use an
enumvalue that cannot be accommodated by the underlying type of theenum(and the underlying type is unsigned).
An n-bit unsigned integer holds values in the range [0, 2n-1]. For instance, c is an 8-bit unsigned char variable that cannot hold the value 256.
unsigned char c = 256;This defect checker depends on the following options:
To determine the sizes of fundamental types, Bug Finder uses your specification for
Target processor type (-target).To determine the underlying types of enumerations, Bug Finder uses your specification for
Enum type definition (-enum-type-definition).
You do not see the defect in these situations:
Creation of new constants from
constvariables (for specific compilers only).Different compilers might define compile-time constants differently. In the following code,
c+1uis considered a compile time-constant by GCC compilers, but not by the standard C compiler:Whether you see a violation of this check onconst uint16_t c = 0xffffu; uint16_t y = c + 1u;ymight depend on your compiler.Bitwise
NOToperation.Polyspace does not raise this violation when you perform a bitwise
NOToperation.
The C standard states that overflowing unsigned integers must be wrapped around (see, for instance, the C11 standard, section 6.2.5). However, the wrap-around behavior can be unintended and cause unexpected results.
Check if the constant value is what you intended. If the value is correct, use a wider data type for the variable.
#define MAX_UNSIGNED_CHAR 255 //Noncompliant
#define MAX_UNSIGNED_SHORT 65535 //Noncompliant
void main() {
unsigned char c1 = MAX_UNSIGNED_CHAR + 1;
unsigned short c2 = MAX_UNSIGNED_SHORT + 1;
}In this example, the defect appears on the macros because at least one use of the macro causes an overflow.
One possible correction is to use a wider data type for the variables that overflow.
#define MAX_UNSIGNED_CHAR 255
#define MAX_UNSIGNED_SHORT 65535
void main() {
unsigned short c1 = MAX_UNSIGNED_CHAR + 1;
unsigned int c2 = MAX_UNSIGNED_SHORT + 1;
}This issue occurs when converting an unsigned integer to a smaller unsigned integer type. If the variable does not have enough bytes to represent the original constant, the conversion overflows.
The exact storage allocation for different floating point types depends on your
processor. See Target processor type (-target).
Integer conversion overflows result in undefined behavior.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the conversion so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling.
In general, avoid conversions to smaller integer types.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
unsigned char convert(void) {
unsigned int unum = 1000000U;
return (unsigned char)unum; //Noncompliant
}In the return statement, the unsigned integer
variable unum is converted to an unsigned character
type. However, the conversion overflows because 1000000 requires at
least 20 bits. The C programming language standard does not view unsigned
overflow as an error because the program automatically reduces the
result by modulo the maximum value plus 1. In this example, unum is
reduced by modulo 2^8 because a character data
type can only represent 2^8-1.
One possible correction is to convert to a different integer
type that can represent the entire number. For example, long.
unsigned long convert(void) {
unsigned int unum = 1000000U;
return (unsigned long)unum;
}This issue occurs when an operation on unsigned integer variables can result in values that cannot be represented by the result data type. The data type of a variable determines the number of bytes allocated for the variable storage and constrains the range of allowed values.
The exact storage allocation for different floating point types depends on your
processor. See Target processor type (-target).
The C11 standard states that unsigned integer overflows result in wrap-around behavior. However, a wrap around behavior might not always be desirable. For instance, if the result of a computation is used as an array size and the computation overflows, the array size is much smaller than expected.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the operation so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling. In the error handling code, you can override the default wrap-around behavior for overflows and implement saturation behavior, for instance.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <limits.h>
unsigned int plusplus(void) {
unsigned uvar = UINT_MAX;
uvar++; //Noncompliant
return uvar;
}In the third statement of this function, the
variable uvar is increased by 1. However, the value
of uvar is the maximum unsigned integer value,
so 1 plus the maximum integer value cannot be represented by an unsigned
int. The C programming language standard does not view unsigned
overflow as an error because the program automatically reduces the
result by modulo the maximum value plus 1. In this example, uvar is
reduced by modulo UINT_MAX. The result is uvar
= 1.
One possible correction is to store the operation
result in a larger data type. In this example, by returning an unsigned
long long instead of an unsigned int,
the overflow error is fixed.
#include <limits.h>
unsigned long long plusplus(void) {
unsigned long long ullvar = UINT_MAX;
ullvar++;
return ullvar;
}Check Information
| Category: Numeric Errors |
Version History
Introduced in R2023a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Sélectionner un site web
Choisissez un site web pour accéder au contenu traduit dans votre langue (lorsqu'il est disponible) et voir les événements et les offres locales. D’après votre position, nous vous recommandons de sélectionner la région suivante : .
Vous pouvez également sélectionner un site web dans la liste suivante :
Comment optimiser les performances du site
Pour optimiser les performances du site, sélectionnez la région Chine (en chinois ou en anglais). Les sites de MathWorks pour les autres pays ne sont pas optimisés pour les visites provenant de votre région.
Amériques
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)