Signed integer overflow is undefined behavior (see undefined behavior 36 in Annex J of the C Standard). Consequently, implementations have considerable latitude in how they deal with signed integer overflow (see MSC15-C. Do not depend on undefined behavior). An implementation may define the same modulo arithmetic for both unsigned and signed integers. On such an implementation, signed integers overflow by wrapping around to 0. An example of such an implementation is GNU GCC invoked with the -fwrapv
command-line option.
Other implementations may cause a hardware trap (also called an exceptional condition) to be generated when a signed integer overflows. On such implementations, a program that causes a signed integer to overflow will most likely abnormally exit. On a UNIX system, the result of such an event may be a signal sent to the process. An example of such an implementation is GNU GCC invoked with the -ftrapv
command-line option.
Still other implementations may simply assume that signed integers never overflow and may generate object code accordingly. An example of such an implementation is GNU GCC invoked without either the -fwrapv
or the -ftrapv
option.
It is also that defines signed integer types as being modulo, for example, need not detect integer overflow. Implementations may also trap on signed arithmetic overflows, or simply assume that overflows will never happen and generate object code accordingly. It is also possible for the same conforming implementation to emit code that exhibits different behavior in different contexts. For example, an implementation may determine that a signed integer loop control variable declared in a local scope cannot overflow and may emit efficient code on the basis of that determination, while the same implementation may avoid making that assumption in another function when the variable is a global objectdetermine that a global variable used in as similar context will wrap.
For these reasons, it is important to ensure that operations on signed integers do no result in overflow. (See MSC15-C. Do not depend on undefined behavior.) Of particular importance are operations on signed integer values that originate from untrusted sources and are used in any of the following ways:as:
- integer operands of
- As an array index
- In any pointer arithmetic
- As a length or size of an object
- As the bound of an array (for example, a loop counter)
- , including array indexing;
- the assignment expression for the declaration of a variable length array;
- the postfix expression preceding square brackets
[]
or the expression in square brackets[]
of a subscripted designation of an element of an array object; and - function arguments of type
size_t
orrsize_t
(for example, As an argument to a memory allocation function - In security-critical code
- ).
Most integer operations can result in overflow if the resulting value cannot be represented by the underlying representation of the integer. The following table indicates which operators can result in overflow:
...
The following sections examine specific operations that are susceptible to integer overflow. When operating on small integer types (smaller than int
), integer promotions are applied. The usual arithmetic conversions may also be applied to (implicitly) convert operands to equivalent types before arithmetic operations are performed. Programmers should understand integer conversion rules before trying to implement secure arithmetic operations. (See INT02-C. Understand integer conversion rules.)
Implementation Details
An example of implementation that defines the same modulo arithmetic for both unsigned and signed integers is GNU GCC invoked with the -fwrapv
command-line option. Other implementations may cause a hardware trap (also called an exceptional condition) to be generated when a signed integer overflows. On such implementations, a program that causes a signed integer to overflow will most likely abnormally exit. On a UNIX system, the result of such an event may be a signal sent to the process. An example of such an implementation is GNU GCC invoked with the -ftrapv
command-line option. Still other implementations may simply assume that signed integers never overflow and may generate object code accordingly. An example of such an implementation is GNU GCC invoked without either the -fwrapv
or the -ftrapv
option.
Anchor | ||||
---|---|---|---|---|
|
Addition
...
Code Block | ||||
---|---|---|---|---|
| ||||
void func(signed long s_a, signed long s_b) { signed long result; if (s_b == 0) { /* Handle error */ } else { result = s_a % s_b; } /* ... */ } |
Implementation Details
On x86 platforms, the remainder operator for signed integers is implemented by the idiv
instruction code, along with the divide operator. Because LONG_MIN / -1
overflows, this code will throw a floating-point exception on LONG_MIN % -1
.
...
The C Standard, 6.5.7 paragraph 4 [ISO/IEC 9899:2011], states
...
In almost every case, an attempt to shift by a negative number of bits or by more bits than exist in the operand indicates a bug (logic error). These issues are covered by INT34-C. Do not shift a negative number of bits or more bits than exist in the operand.
Noncompliant Code Example
This noncompliant code example can result in an unrepresentable value.
...
Compliant Solution
This compliant solution eliminates the possibility of overflow resulting from a left-shift operation:
...