...
Code Block | ||||
---|---|---|---|---|
| ||||
int si_a; int si_b; int sresult; void func(void) { /* Initialize si_a and si_b */ sresult = si_a << si_b; /* ... */ } |
Shift operators and other bitwise operators should be used only with unsigned integer operands in accordance with INT13-C. Use bitwise operators only on unsigned operands.
...
Code Block | ||||
---|---|---|---|---|
| ||||
unsigned int ui_a; unsigned int ui_b; unsigned int uresult; void func(void) { /* Initialize ui_a and ui_b */ uresult = ui_a << ui_b; /* ... */ } |
Compliant Solution (Left Shift, Unsigned Type)
...
Code Block | ||||
---|---|---|---|---|
| ||||
unsigned int ui_a; unsigned int ui_b; unsigned int uresult; void func(void) { /* Initialize ui_a and ui_b */ if (ui_b >= sizeof(unsigned int)*CHAR_BIT) { /* Handle error condition */ } else { uresult = ui_a << ui_b; } /* ... */ } |
Modulo behavior resulting from left-shifting an unsigned integer type is permitted by this standard.
...
Code Block | ||||
---|---|---|---|---|
| ||||
unsigned int ui_a; unsigned int ui_b; unsigned int uresult; void func(void) { /* Initialize ui_a and ui_b */ uresult = ui_a >> ui_b; /* ... */ } |
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-C. Use bitwise operators only on unsigned operands.
...
This compliant solution tests the suspect shift operations to guarantee there is no possibility of undefined behavior:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> unsigned int ui_a; unsigned int ui_b; unsigned int uresult; void func(void) { /* Initialize ui_a and ui_b */ if (ui_b >= sizeof(unsigned int) * CHAR_BIT) { /* Handle error condition */ } else { uresult = ui_a >> ui_b; } /* ... */ } |
Implementation Details
GCC has no options to handle shifts by negative amounts or by amounts outside the width of the type predictably or trap on them; they are always treated as undefined. Processors may reduce the shift amount modulo the width of the type. For example, 32-bit shifts are implemented using the following instructions on IA-32:
...