Integer constants are often used as masks or specific bit values. Frequently, these constants are expressed in hexadecimal form to indicate to the programmer how the data might be represented in the machine. However, Hexadecimal integer constants are frequently used in a non-portable manner.
The noncompliant code example attempts to take two's complement of a value of type unsigned long
using a mask.
const unsigned long mask = 0xFFFFFFFF; unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
This code produces the two's complement of x
for implementations where unsigned long
have a precision of 32 bits. However, on implementations where unsigned long
has a precision of 64 bits, this code does not produce the two's complement of x
. Because only the lower order 32-bits are set, the resulting value of mask
is 0x00000000FFFFFFFF.
A portable (and safer) way to set all the bits on in an integer constant of type unsigned long
is to define a constant with a value of ~0
.
const unsigned long mask = ~0; unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
This compliant solution sets all the bits in the value regardless of representation.
In this noncompliant code example, a programmer is attempting to set the most significant bit.
const unsigned long mask = 0x80000000; unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
This code has the desired effect for implementations where unsigned long
have a precision of 32 bits but not on implementations where unsigned long
has a precision of 64 bits.
A portable (and safer) way of setting the high order bit is to use a shift expression as in this compliant solution.
const unsigned long mask = (1 << ((sizeof(unsigned long) * CHAR_BIT) - 1)) unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
Vulnerabilities are frequently introduced while porting code. A buffer overflow vulnerability may result, for example, if an incorrectly defined integer constant is used to determine the size of a buffer. It is always best to write portable code, especially when there is no performance overhead for doing so.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
INT17-C |
high |
probable |
low |
P6 |
L2 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
C++ Secure Coding Standard: INT17-CPP. Define integer constants in an implementation-independent manner
\[[Dewhurst 2002|AA. Bibliography#Dewhurst 02]\] Gotcha #25, "#define Literals" \[[ISO/IEC 9899-1999|AA. Bibliography#ISO/IEC 9899-1999]] Section 6.4.4.1, "Integer constants" |