...
| Code Block | ||||
|---|---|---|---|---|
| ||||
unsignedint compute(int x) { int y = x << 502; x += (x << 2) + 1; y + 1; return x; } // ... int x = compute(50); |
Although this is a valid manipulation, the result of the shift depends on the underlying representation of the integer type and is consequently implementation-defined. Additionally, the readability of the code is reduced.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
unsignedint compute(int x) = 50; x ={ return 5 * x + 1; } // ... int x = compute(50); |
A reviewer may now recognize that the operation should also be checked for wrapping. This might not have been apparent in the original, noncompliant code example.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
int compute(int x) { x >>= -50; x >>= 2 2; return x; } // ... int x = compute(-50); |
Although this code is likely to perform the division correctly, it is not guaranteed to. If x has a signed type and a negative value, the operation is implementation-defined and can be implemented as either an arithmetic shift or a logical shift. In the event of a logical shift, if the integer is represented in either one's complement or two's complement form, the most significant bit (which controls the sign for both representations) will be set to 0, causing a once negative number to become a possibly very large, positive number. For more details, see INT13-C. Use bitwise operators only on unsigned operands.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
int compute(int x) { return x =/ -50; x /= 44; } // ... int x = compute(-50); |
The resulting value is now more likely to be consistent with the programmer's expectations.
...
INT14-C-EX0: Routines may treat integers as bit vectors for I/O purposes. That is, they may treat an integer as a series of bits in order to write it to a file or socket. They may also read a series of bits from a file or socket and create an integer from the bits. Bitwise operations are also permitted when reading or writing the data from a tightly packed data structure of bytes.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int value = /* Interesting value */
unsigned char bytes[sizeof(int)];
for (int i = 0; i < sizeof(int); i++) {
bytes[i] = value >> (i*8) & 0xFF;
}
/* bytes[] now has same bit representation as value */ |
NUM01-J-EX1: Bitwise operations may be used to construct constant expressions.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int limit = (1 << 17) - 1; // 2^17 - 1 = 131071 |
Nevertheless, as a matter of style, it is preferable to replace such constant expressions with the equivalent hexadecimal constants.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int limit = 0x1FFFF; // 2^17 - 1 = 131071 |
Risk Assessment
Performing bit manipulation and arithmetic operations on the same variable obscures the programmer's intentions and reduces readability. It also makes it more difficult for a security auditor or maintainer to determine which checks must be performed to eliminate security flaws and ensure data integrity.
Recommendation | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level | |
|---|---|---|---|
INT14-C | Medium | Unlikely | Yes |
No | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description |
|---|---|---|---|
| Compass/ROSE |
Can detect violations of this recommendation. However, it can detect only those violations where both bitwise and arithmetic operators are used in the same expression |
5.0
Can detect violations of this recommendation with the CERT C Rule Pack
| LDRA tool suite |
| 585 S | Fully implemented | ||||||
| Polyspace Bug Finder |
| CERT C: Rec. INT14-C | Checks for bitwise and arithmetic operation on the same data (rec. fully covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
...
...