Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changes to examples to match new coding guidelines

...

Code Block
bgColor#FFcccc
langc
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
bgColor#FFcccc
langc
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
bgColor#ccccff
langc
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
bgColor#FFcccc
langc
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
bgColorccccff#ccccff
langc
#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:

...