...
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
...