...
Code Block | ||||
---|---|---|---|---|
| ||||
int si_a; int si_b; int sum; void func(void) { /* Initialize si_a and si_b */ sum = si_a + si_b; /* ... */ } |
Compliant Solution
...
This compliant solution performs a precondition test of the operands of the addition tests the suspect addition operation to ensure no overflow occurs , assuming two's complement regardless of representation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> signed int si_a; signed int si_b; signed int sum; void (func(void) { /* Initialize si_a, si_b and sum */ if (((si_a^si_b) | > 0) && (si_a > (INT_MAX - (((si_a^(~(si_a^si_b) & INT_MIN)) +|| ((si_b)^si < 0) && (si_a < (INT_MIN - si_b)) >= 0)) { /* Handle error condition */ } else { sum = si_a + si_b; } /* ... */ } |
This compliant solution works only on architectures that use two's complement representation. Although most modern platforms use two's complement representation, it is best not to introduce unnecessary platform dependencies. (See MSC14-C. Do not introduce unnecessary platform dependencies.) This solution can also be more expensive than a postcondition test, especially on RISC CPUs.
Compliant Solution (General)
This compliant solution tests the suspect addition operation to ensure no overflow occurs regardless of representation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h>
signed int si_a;
signed int si_b;
signed int sum;
void (func) {
/* Initialize si_a, si_b and sum */
if (((si_b > 0) && (si_a > (INT_MAX - si_b))) ||
((si_b < 0) && (si_a < (INT_MIN - si_b)))) {
/* Handle error condition */
} else {
sum = si_a + si_b;
}
/* ... */
} |
This solution is more readable but may be less efficient than the solution that is specific to two's complement representation.
...
Anchor | ||||
---|---|---|---|---|
|
Subtraction
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. 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 ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element for information about pointer subtraction. Decrementing is equivalent to subtracting 1.
Noncompliant Code Example
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 | ||||
---|---|---|---|---|
| ||||
signed int si_a;
signed int si_b;
signed int result;
void func(void) {
/* Initialize si_a and si_b */
|
...
Subtraction
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. 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 ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element for information about pointer subtraction. Decrementing is equivalent to subtracting 1.
Noncompliant Code Example
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 | ||||
---|---|---|---|---|
| ||||
signed int si_a;
signed int si_b;
signed int result;
void func(void) {
/* Initialize si_a and si_b */
result = si_a - si_b;
/* ... */
} |
Compliant Solution (Two's Complement)
This compliant solution tests the operands of the subtraction to guarantee there is no possibility of signed overflow, presuming two's complement representation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> signed int si_a; signed int si_b; signed int result; void func(void) { /* Initialize si_a, si_b and result */ if (((si_a^si_b) & (((si_a ^ ((si_a^si_b) & INT_MIN)) - si_b)^si_b)) < 0) { /* Handle error condition */ } else { result = si_a - si_b; } /* ... */ } |
...
Compliant Solution
...
This compliant solution tests the operands of the subtraction to guarantee there is no possibility of signed overflow, regardless of representation:
...
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si_a; signed int si_b; signed int result; void func(void) { /* Initialize si_a and si_b */ result = si_a * si_b; /* ... */ } |
Compliant Solution
This compliant solution guarantees there is no possibility of signed overflow on systems where long long
is at least twice the width of int
:
...
Code Block | ||||
---|---|---|---|---|
| ||||
signed long s_a; signed long s_b; signed long result; void func(void) { /* Initialize s_a and s_b */ result = s_a / s_b; /* ... */ } |
Compliant Solution
This compliant solution guarantees there is no possibility of signed overflow or divide-by-zero errors:
...
Code Block | ||||
---|---|---|---|---|
| ||||
signed long s_a; signed long result; void func(void) { /* Initialize s_a */ result = -s_a; /* ... */ } |
Compliant Solution
This compliant solution tests the suspect negation operation to guarantee there is no possibility of signed overflow:
...
Code Block | ||||
---|---|---|---|---|
| ||||
int si_a; int si_b; int sresult; void func(void) { /* Initialize si_a and si_b */ sresult = si_a << si_b; /* ... */ } |
Compliant Solution
This compliant solution eliminates the possibility of overflow resulting from a left-shift operation:
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdatomic.h> atomic_int i; int si_a; void func(void) { /* Initialize i, si_a */ atomic_fetch_add(&i, si_a); /* ... */ } |
Compliant Solution
This compliant solution tests the operands to guarantee there is no possibility of signed overflow. It loads the value stored in the atomic integer and tests for possible overflow before performing the addition:
...