...
Code Block |
---|
|
signed int si1, si2, result;
if (((si1^si2) & (((si1 ^ ((si1^si2) & (1 << (sizeof(int)*CHAR_BIT-1))))-si2)^si2)) < 0) {
/* handle error condition */
}
result = si1 - si2;
|
...
Anchor |
---|
| Multiplication |
---|
| Multiplication |
---|
|
Multiplication
Multiplication is between two operands of arithmetic type.
Non-Compliant Code Example (Signed)
This non-compliant 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 could lead to an exploitable vulnerability.
Code Block |
---|
|
signed int si1, si2, result;
result = si1 * si2;
|
Compliant Solution (Signed)
This compliant solution guarantees there is no possibility of signed overflow.
Code Block |
---|
|
signed int si1, si2, result;
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 */
}
result = (int)tmp;
|
The preceding code is compliant only on systems where long long
is at least twice the size of int
. 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;
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;
|
Non-Compliant Code Example (Unsigned)
Wiki Markup |
---|
The Mozilla Scalable Vector Graphics (SVG) viewer contains a heap buffer overflow vulnerability resulting from an unsigned integer overflow during the multiplication of the {{signed int}} value {{pen->num_vertices}} and the {{size_t}} value {{sizeof(cairo_pen_vertex_t)}} \[[VU#551436|AA. C References#VU551436]\]. The {{signed int}} operand is converted to {{unsigned int}} prior to the multiplication operation (see [INT02-A. Understand integer conversion rules]). |
Code Block |
---|
|
pen->num_vertices = _cairo_pen_vertices_needed(gstate->tolerance, radius, &gstate->ctm);
pen->vertices = malloc(pen->num_vertices * sizeof(cairo_pen_vertex_t));
|
The unsigned integer overflow can result in allocating memory of insufficient size.
Compliant Solution (Unsigned)
This compliant solution tests the suspect multiplication operation to guarantee that there is no unsigned integer overflow.
Code Block |
---|
|
pen->num_vertices = _cairo_pen_vertices_needed(gstate->tolerance, radius, &gstate->ctm);
if (pen->num_vertices > SIZE_MAX/sizeof(cairo_pen_vertex_t)) {
/* handle error condition */
}
pen->vertices = malloc(pen->num_vertices * sizeof(cairo_pen_vertex_t));
|
...
Include Page |
---|
| c:INT32-C-d. Ensure that integer division operations do not result in an overflow |
---|
| c:INT32-C-d. Ensure that integer division operations do not result in an overflow |
---|
|
...