...
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 a tainted source and are used as:
...
Addition is between two operands of arithmetic type or between a pointer to an object type and an integer type. This rule only applies to addition between two operands of arithmetic type. ( See ARR37-C. Do not add or subtract an integer to a pointer to a non-array object and ARR30-C. Do not form or use out of bounds pointers or array subscripts.)
Incrementing is equivalent to adding 1.
...
This noncompliant code example may result in a signed integer overflow during the addition of the signed operands si_a
and si_b
. If this behavior is unanticipated, it can lead to an exploitable vulnerability.
Code Block | ||||
---|---|---|---|---|
| ||||
void func(signed int si_a, signed int si_b) {
signed int sum = si_a + si_b;
/* ... */
} |
Compliant Solution
This compliant solution tests ensures that the suspect addition operation to ensure no cannot overflow occurs , regardless of representation:
...
Subtraction is between two operands of arithmetic type, two pointers to qualified or unqualified versions of compatible object types, or a pointer to an object type and an integer type. This rule only applies to subtraction between two operands of arithmetic type. See ARR36-C. Do not subtract or compare two pointers that do not refer to the same array, ARR37-C. Do not add or subtract an integer to a pointer to a non-array object, and ARR30-C. Do not form or use out of bounds pointers or array subscripts for information about pointer subtraction.
Decrementing is equivalent to subtracting 1.
...
This noncompliant code example can result in a signed integer overflow during the subtraction of the signed operands si_a
and si_b
. If this behavior is unanticipated, the resulting value may be used to allocate insufficient memory for a subsequent operation or in some other manner that can lead to an exploitable vulnerability.
Code Block | ||||
---|---|---|---|---|
Code Block | ||||
| ||||
void func(signed int si_a, signed int si_b) {
signed int diff = si_a - si_b;
/* ... */
} |
Compliant Solution
...
This noncompliant code example can result in a signed integer overflow during the multiplication of the signed operands si_a
and si_b
. If this behavior is unanticipated, the resulting value may be used to allocate insufficient memory for a subsequent operation or in some other manner that can lead to an exploitable vulnerability.
Code Block | ||||
---|---|---|---|---|
| ||||
void func(signed int si_a, signed int si_b) {
signed int result = si_a * si_b;
/* ... */
} |
Compliant Solution
The product of two operands can always be represented using twice the number of bits in the larger of the two operands. This compliant solution guarantees there is no possibility of eliminates signed overflow on systems where long long
is at least twice the width of int
:
...
The assertion fails if long long
has less than twice the width of int
. The purpose of the UWIDTH()
macro and the function popcount()
is explained in INT19-C. Correctly compute integer widths.
On systems where this assertion would fail, this The following portable compliant solution may can be used to ensure signed overflow does not occurfor implementations where this assertion fails:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> void func(signed int si_a, signed int si_b) { signed int result; if (si_a > 0) { /* si_a is positive */ if (si_b > 0) { /* si_a and si_b are positive */ if (si_a > (INT_MAX / si_b)) { /* Handle error */ } } else { /* si_a positive, si_b nonpositive */ if (si_b < (INT_MIN / si_a)) { /* Handle error */ } } /* si_a positive, si_b nonpositive */ } else { /* si_a is nonpositive */ if (si_b > 0) { /* si_a is nonpositive, si_b is positive */ if (si_a < (INT_MIN / si_b)) { /* Handle error */ } } else { /* si_a and si_b are nonpositive */ if ( (si_a != 0) && (si_b < (INT_MAX / si_a))) { /* Handle error */ } } /* End if si_a and si_b are nonpositive */ } /* End if si_a is nonpositive */ result = si_a * si_b; } |
...
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:
...