...
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2 E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined and may be either an arithmetic (signed) shift as shown below :
or a logical (unsigned) shift.:
This non-compliant code example fails to test if the right operand negative or is greater than or equal to the width of the promoted left operand, allowing undefined behavior.
| Code Block | ||
|---|---|---|
| ||
int si1, si2, sresult; unsigned int ui1, ui2, uresult; sresult = si1 >> si2; uresult = ui1 >> ui2; |
| Wiki Markup |
|---|
Making assumptions about whether a right shift is implemented as an arithmetic (signed) shift or a logical (unsigned) shift can also lead to vulnerabilities (see \[[INT13-A|INT13-A. Do not assume that a right shift operation is implemented as a logical or an arithmetic shift]\]). |
Compliant Solution (right shiftCompliant Solution (rightshift)
This compliant solution tests the suspect shift operation to guarantee there is no possibility of unsigned overflow.
| Code Block | ||
|---|---|---|
| ||
int si1, si2, sresult;
unsigned int ui1, ui2, result;
if ( (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) ) {
/* handle error condition */
}
else {
sresult = si1 >> si2;
}
if (ui2 >= sizeof(unsigned int)*CHAR_BIT) {
/* handle error condition */
}
else {
uresult = ui1 >> ui2;
}
|
As already noted, if the left operand has a signed type and a negative value, the resulting right shift could be either an arithmetic (signed) shift or a logical (unsigned) shift. For implementations in which an arithmetic shift is performed, and the sign bit can be propagated as the number is shifted.
| Code Block | ||
|---|---|---|
| ||
int stringify;
char buf[sizeof("256")];
sprintf(buf, "%u", stringify >> 24);
|
If stringify has the value 0x80000000, stringify>> 24 evaluates to 0xFFFFFF80 and the subsequent call to sprintf() results in a buffer overflow.
...
Exceptions
Unsigned integers can be allowed to exhibit modulo behavior if and only if
...