You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

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.

Noncompliant Code Example

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.

Compliant Solution

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.

Noncompliant Code Example

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.

Compliant Solution

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;

Risk Assessment

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

Related Vulnerabilities

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

Other Languages

This rule appears in the C++ Secure Coding Standard as INT17-CPP. Define integer constants in an implementation-independent manner.

References

[Dewhurst 02] Gotcha #25, "#define Literals"
[ISO/IEC 9899-1999] Section 6.4.4.1, "Integer constants"


      04. Integers (INT)      

  • No labels