Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Removed references to Annex K.

Bitwise operators include the complement operator (~), bitwise shift operators ( >> and <<), bitwise AND operator (&), bitwise exclusive OR operator (^), and bitwise inclusive OR operator (|) | and compound assignment operators >>=, <<=, &=, ^= and |=. Bitwise operators should only be used with only with unsigned integer operands, as the results of some bitwise operations on signed integers is implementation-defined.

Non-Compliant Code Example (right shift)

Wiki Markup
The right-shift operation may be implemented as either an arithmetic (signed) shift or a logical (unsigned) shift. If {{E1}} in the expression {{E1 >> E2}} has a signed type and a negative value, the resulting value is implementation-defined. Also, be careful to avoid [undefined behavior|BB. Definitions#undefined behavior] while performing a bitwise shift (see [INT34-C. Do not shift a negative number of bits or more bits than exist in the operand]). This non-compliant code example can result in an error condition on [implementations|BB. Definitions#implementation] in which an arithmetic shift is performed and the sign bit can be propagated as the number is shifted \[[Dowd 06|AA. C References#Dowd 06]\].

integers are implementation-defined.

The C11 standard, section 6.5, paragraph 4 [ISO/IEC 9899:2011], states:

Some operators (the unary operator ~ , and the binary operators <<, >>, &, ^, and |, collectively described as bitwise operators) shall have operands that have integral type. These operators return values that depend on the internal representations of integers, and thus have implementation-defined and undefined aspects for signed types.

Furthermore, the bitwise shift operators << and >> are undefined under many circumstances, and are implementation-defined for signed integers for more circumstances; see rule INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand for more information.

Implementation details

The Microsoft C compiler documentation says that:

Bitwise operations on signed integers work the same as bitwise operations on unsigned integers.

On-line GCC documentation about the implementation of bitwise operations on signed integers says:

Bitwise operators act on the representation of the value including both the sign and value bits, where the sign bit is considered immediately above the highest-value value bit.

Noncompliant Code Example (Right Shift)

The right-shift operation may be implemented as either an arithmetic (signed) shift or a logical (unsigned) shift. If E1 in the expression E1 >> E2 has a signed type and a negative value, the resulting value is implementation-defined. Also, a bitwise shift can result in undefined behavior. (See INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand.)

This noncompliant code example can result in an error condition on implementations in which an arithmetic shift is performed, and the sign bit is propagated as the number is shifted [Dowd 2006]:

Code Block
bgColor#FFcccc
langc
Code Block
bgColor#FFcccc

int rc = 0;
int stringify = 0x80000000;
char buf[sizeof("256")];
rc = snprintf(buf, sizeof(buf), "%u", stringify >> 24);
if (rc == -1 || rc >= sizeof(buf)) {
  /* handleHandle error */
}

In this example, stringify >> 24 evaluates to 0xFFFFFF80, or 4,294,967,168. When converted to a string, the resulting value "4294967168" is too large to store in buf and is truncated by snprintf().

If this code had been implemented using sprintf() instead of snprintf(), this non-compliant noncompliant code example would have resulted in a buffer overflow.

Compliant Solution (

...

Right Shift)

In this compliant solution, stringify is declared as an unsigned integer. The value of the result of the right-shift operation is the integral part of the quotient of stringify / 2 ^ 24.:

Code Block
bgColor#ccccff
langccccffc

int rc = 0;
unsigned int stringify = 0x80000000;
char buf[sizeof("256")];
rc = snprintf(buf, sizeof(buf), "%u", stringify >> 24);
if (rc == -1 || rc >= sizeof(buf)) {
  /* handleHandle error */
}

Also, consider using the sprintf_s() function defined in ISO/IEC TR 24731-1 instead of snprintf() to provide some additional checks (see STR07-A. Use TR 24731 for remediation of existing string manipulation code).

Exceptions

INT13-C-EX1: When used as bit flags, it is acceptable to use preprocessor macros or enumeration constants as arguments to the & and | operators even if the value is not explicitly declared as unsigned.

Code Block
bgColor#ccccff
langc

fd = open(file_name, UO_WRONLY | UO_CREAT | UO_EXCL | UO_TRUNC, 0600);

INT13-C-EX2: If the right hand -side operand to a shift operator is known at compile time, it is acceptable for the value to be represented with a signed type in the compiler so long as the provided it is positive.

Code Block
bgColor#ccccff
langc

#define SHIFT 24
foo = 15u >> SHIFT;

Risk Assessment

Improper range checking Performing bitwise operations on signed numbers can lead to buffer overflows and the execution of arbitrary code by an attacker in some cases, unexpected or implementation-defined behavior in others.

Recommendation

Severity

Likelihood

Remediation Cost

Detectable

Repairable

Priority

Level

INT13-

A

C

High

high

Unlikely

unlikely

Yes

medium

No

P6

L2

Automated Detection

...

The LDRA tool suite V 7.6.0 can detect violations of this recommendation.

Fortify SCA Version 5.0 with the CERT C Rule Pack can detect violations of this recommendation.

Splint Version 3.1.1 can detect violations of this recommendation.

...

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
bitop-typeFully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-INT13
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
LANG.TYPE.IOTInappropriate operand type
Compass/ROSE



Can detect violations of this rule. In particular, it flags bitwise operations that involved variables not declared with unsigned type

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.INT13

Fully implemented

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C4532, C4533, C4534, C4543, C4544


Klocwork
Include Page
Klocwork_V
Klocwork_V
MISRA.BITS.NOT_UNSIGNED
MISRA.BITS.NOT_UNSIGNED.PREP

LDRA tool suite
Include Page
LDRA_V
LDRA_V

50 S
120 S
331 S

Fully implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V
CERT_C-INT13-a
CERT_C-INT13-b
Operands of bitwise and complement operators shall have an unsigned type
Operands of shift operators shall have an unsigned type
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

9233

Partially supported: reports use of a bitwise operator on an expression with a signed MISRA C 2004 underlying type

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. INT13-C


Checks for bitwise operation on negative value (rec. fully covered)

RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
bitop-typeFully checked
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V

S874


Splint
Include Page
Splint_V
Splint_V



Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

...

Related Guidelines

SEI CERT C++ Coding StandardVOID INT13-CPP. Use bitwise operators only on unsigned operands
ISO/IEC TR 24772:2013Bit Representations [STR]
Arithmetic Wrap-around Error [FIF]
Sign Extension Error [XZI]
MITRE CWECWE-682, Incorrect calculation

Bibliography

[Dowd 2006]Chapter 6, "C Language Issues"
[C99 Rationale 2003]Subclause

...

6.5.7,

...

"Bitwise Shift Operators"


...

Image Added Image Added Image Added shift operators" \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.5.7, "Bitwise shift operators" \[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "STR Bit Representations," "XYY Wrap-around Error," and "XZI Sign Extension Error"INT12-A. Do not make assumptions about the type of a plain int bit-field when used in an expression      04. Integers (INT)       INT14-A. Avoid performing bitwise and arithmetic operations on the same data