...
This noncompliant code example may result in a signed integer overflow during the addition of the signed operands si1
and si2
. If this behavior is unanticipated, it can lead to an exploitable vulnerability.
Code Block | ||||
---|---|---|---|---|
| ||||
int si1, si2, sum; /* Initialize si1 and si2 */ sum = si1 + si2; |
...
This compliant solution performs a pre-condition test of the operands of the addition to ensure no overflow occurs, assuming two's complement representation.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, si2, sum; /* Initialize si1 and si2 */ if ( ((si1^si2) | (((si1^(~(si1^si2) & INT_MIN)) + si2)^si2)) >= 0) { /* handle error condition */ } else { sum = si1 + si2; } |
...
This compliant solution tests the suspect addition operation to ensure no overflow occurs regardless of representation.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, si2, sum; /* Initialize si1 and si2 */ if (((si2>0) && (si1 > (INT_MAX-si2))) || ((si2<0) && (si1 < (INT_MIN-si2)))) { /* handle error condition */ } else { sum = si1 + si2; } |
...
This noncompliant code example can result in a signed integer overflow during the subtraction of the signed operands si1
and si2
. 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 si1, si2, result; /* Initialize si1 and si2 */ result = si1 - si2; |
...
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 | ||||
---|---|---|---|---|
| ||||
signed int si1, si2, result; /* Initialize si1 and si2 */ if (((si1^si2) & (((si1 ^ ((si1^si2) & (1 << (sizeof(int)*CHAR_BIT-1))))-si2)^si2)) < 0) { /* handle error condition */ } else { result = si1 - si2; } |
...
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 si1, si2, result; /* Initialize si1 and si2 */ if ((si2 > 0 && si1 < INT_MIN + si2) || (si2 < 0 && si1 > INT_MAX + si2)) { /* handle error condition */ } else { result = si1 - si2; } |
...
This noncompliant code example can result in a signed integer overflow during the multiplication of the signed operands si1
and si2
. 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 si1, si2, result; /* ... */ result = si1 * si2; |
...
This compliant solution guarantees there is no possibility of signed overflow on systems where long long
is at least twice the size of int
.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, si2, result; /* Initialize si1 and si2 */ static_assert( sizeof(long long) >= 2 * sizeof(int), "Unable to detect overflow after multiplication" ); signed long long tmp = (signed long long)si1 * (signed long long)si2; /* * If the product cannot be represented as a 32-bit integer, * handle as an error condition. */ if ( (tmp > INT_MAX) || (tmp < INT_MIN) ) { /* handle error condition */ } else { result = (int)tmp; } |
...
On systems where this relationship does not exist, the following compliant solution may be used to ensure signed overflow does not occur.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, si2, result; /* Initialize si1 and si2 */ if (si1 > 0){ /* si1 is positive */ if (si2 > 0) { /* si1 and si2 are positive */ if (si1 > (INT_MAX / si2)) { /* handle error condition */ } } /* end if si1 and si2 are positive */ else { /* si1 positive, si2 non-positive */ if (si2 < (INT_MIN / si1)) { /* handle error condition */ } } /* si1 positive, si2 non-positive */ } /* end if si1 is positive */ else { /* si1 is non-positive */ if (si2 > 0) { /* si1 is non-positive, si2 is positive */ if (si1 < (INT_MIN / si2)) { /* handle error condition */ } } /* end if si1 is non-positive, si2 is positive */ else { /* si1 and si2 are non-positive */ if ( (si1 != 0) && (si2 < (INT_MAX / si1))) { /* handle error condition */ } } /* end if si1 and si2 are non-positive */ } /* end if si1 is non-positive */ result = si1 * si2; |
...
This noncompliant code example can result in a signed integer overflow during the division of the signed operands sl1
and sl2
or in a divide-by-zero error. The IA-32 architecture, for example, requires that both conditions result in a fault, which can easily result in a denial-of-service attack.
Code Block | ||||
---|---|---|---|---|
| ||||
signed long sl1, sl2, result; /* Initialize sl1 and sl2 */ result = sl1 / sl2; |
...
This compliant solution guarantees there is no possibility of signed overflow or divide-by-zero errors.
Code Block | ||||
---|---|---|---|---|
| ||||
signed long sl1, sl2, result; /* Initialize sl1 and sl2 */ if ( (sl2 == 0) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) { /* handle error condition */ } else { result = sl1 / sl2; } |
...
This noncompliant code example can result in a divide-by-zero error. Furthermore, many hardware platforms implement modulo as part of the division operator, which can overflow. Overflow can occur during a modulo operation when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to — 1. This occurs in spite of the fact that the result of such a modulo operation should theoretically be 0.
Code Block | ||||
---|---|---|---|---|
| ||||
signed long sl1, sl2, result; result = sl1 % sl2; |
...
This compliant solution tests the modulo operand to guarantee there is no possibility of a divide-by-zero error or an (internal) overflow error.
Code Block | ||||
---|---|---|---|---|
| ||||
signed long sl1, sl2, result; /* Initialize sl1 and sl2 */ if ( (sl2 == 0 ) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) { /* handle error condition */ } else { result = sl1 % sl2; } |
...
Furthermore, it guarantees that the minumum signed value modulo -1 yields 0.
Code Block | ||||
---|---|---|---|---|
| ||||
signed long sl1, sl2, result; /* Initialize sl1 and sl2 */ if (sl2 == 0) { /* handle error condition */ } else { if ((sl2 < 0) && (sl2 != LONG_MIN)) { sl2 = -sl2; } result = sl1 % sl2; } |
...
This noncompliant code example can result in a signed integer overflow during the unary negation of the signed operand si1
.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, result; /* Initialize si1 */ result = -si1; |
...
This compliant solution tests the suspect negation operation to guarantee there is no possibility of signed overflow.
Code Block | ||||
---|---|---|---|---|
| ||||
signed int si1, result; /* Initialize si1 */ if (si1 == INT_MIN) { /* handle error condition */ } else result = -si1; } |
...
This noncompliant code example can result in signed integer overflow.
Code Block | ||||
---|---|---|---|---|
| ||||
int si1, si2, sresult; /* Initialize si1 and si2 */ sresult = si1 << si2; |
...
This compliant solution eliminates the possibility of overflow resulting from a left-shift operation.
Code Block | ||||
---|---|---|---|---|
| ||||
int si1, si2, sresult; /* Initialize si1 and si2 */ if ( (si1 < 0) || (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) || (si1 > (INT_MAX >> si2)) ) { /* handle error condition */ } else { sresult = si1 << si2; } |
...