...
Conversions between integers and pointers can have undesired consequences depending on the implementation.
According to the to the C Standard, subclause 6.3.2.3 3 [ISO/IEC 9899:20112024],
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
...
The result of this assignment is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
Compliant Solution
Adding an explicit cast may help the compiler convert the integer value into a valid pointer. A common technique is to assign the integer to a volatile-qualified object of type intptr_t
or uintptr_t
and then assign the integer value to the pointer:
...
bgColor | #ccccff |
---|---|
lang | c |
...
Unfortunately this code cannot be made safe while strictly conforming to ISO C.
A particular platform (that is, hardware, operating system, compiler, and Standard C library) might guarantee that a memory address is correctly aligned for the pointer type, and actually contains a value for that type. A common practice is to use addresses that are known to point to hardware that provides valid values.
Exceptions
INT36-C-EX1: A null pointer can be converted to an integer; it takes on the value 0. Likewise, the integer value 0 The integer value 0 can be converted to a pointer; it becomes the null pointer.
...
Tool | Version | Checker | Description | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Astrée |
| pointer-integral-cast pointer-integral-cast-implicit function-pointer-integer-cast function-pointer-integer-cast-implicit | Fully checked | |||||||||||||||||||
Axivion Bauhaus Suite |
| CertC-INT36 | Fully implemented | |||||||||||||||||||
Clang |
| -Wint-to-pointer-cast , -Wint-conversion | Can detect some instances of this rule, but does not detect all | |||||||||||||||||||
CodeSonar |
| LANG.CAST.PC.CONST2PTR LANG.CAST.PC.INT | Conversion: integer constant to pointer Conversion: pointer/integer | |||||||||||||||||||
Compass/ROSE | ||||||||||||||||||||||
Coverity |
| PW.POINTER_CONVERSION_LOSES_BITS | Fully implemented | |||||||||||||||||||
Cppcheck Premium |
| premium-cert-int36-c | Partially implemented | |||||||||||||||||||
Helix QAC |
| C0303, C0305, C0306, C0309, C0324, C0326, C0360, C0361, C0362 C++3040, C++3041, C++3042, C++3043, C++3044, C++3045, C++3046, C++3047, C++3048 | ||||||||||||||||||||
Klocwork |
| MISRA.CAST.OBJ_PTR_TO_INT.2012 | ||||||||||||||||||||
LDRA tool suite |
| 439 S, 440 S | Fully implemented | |||||||||||||||||||
Parasoft C/C++test |
| MISRA2008-5_2_8, CODSTA-127_b | Fully implemented | CERT_C-INT36-b | A conversion should not be performed between a pointer to object type and an integer type other than 'uintptr_t' or 'intptr_t' | |||||||||||||||||
PC-lint Plus |
| 4287 | Partially supported: reports casts from pointer types to smaller integer types which lose information | |||||||||||||||||||
Polyspace Bug Finder |
| Checks for unsafe | Polyspace Bug Finder | R2016b | Unsafeconversion between pointer and integer | Misaligned or invalid results from conversions between pointer and integer types | (rule partially covered) | |||||||||||||||
PVS-StudioPRQA QA-C |
| 305V527, 306, 309, 429, 432, 557, 563, 671, 674 | Partially implemented | PVS-Studio | 6.22 | V528, V542, V566, V601, V647, V1091 | ||||||||||||||||
RuleChecker |
| pointer-integral-cast pointer-integral-cast-implicit function-pointer-integer-cast function-pointer-integer-cast-implicit | Fully checked | |||||||||||||||||||
SonarQube C/C++ Plugin |
| S1767 | Partially implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
Taxonomy | Taxonomy item | Relationship |
---|---|---|
CERT C | INT11-CPP. Take care when converting from pointer to integer or integer to pointer | Prior to 2018-01-12: CERT: Unspecified Relationship |
ISO/IEC TR 24772:2013 | Pointer Casting and Pointer Type Changes [HFC] | Prior to 2018-01-12: CERT: Unspecified Relationship |
ISO/IEC TS 17961:2013 | Converting a pointer to integer or integer to pointer [intptrconv] | Prior to 2018-01-12: CERT: Unspecified Relationship |
CWE 2.11 | CWE-587, Assignment of a Fixed Address to a Pointer | 2017-07-07: CERT: Partial overlap |
CWE 2.11 | CWE-704 | 2017-06-14: CERT: Rule subset of CWE |
CWE 2.11 | CWE-758 | 2017-07-07: CERT: Rule subset of CWE |
CWE 3.1 | CWE-119, Improper Restriction of Operations within the Bounds of a Memory Buffer | 2018-10-19:CERT:None |
CWE 3.1 | CWE-466, Return of Pointer Value Outside of Expected Range | 2018-10-19:CERT:None |
CERT-CWE Mapping Notes
Key here for mapping notes
...
- Setting a pointer to a valid integer value (eg points to an object of the correct t ype)
INT36-C – CweCWE-587 =
- Illegal pointer-to-integer conversion
Intersection(INT36-C,CWE-466) = ∅
Intersection(INT36-C,CWE-466) = ∅
An example explaining the above two equations follows:
static char x[3];
char* foo() {
int x_int = (int) x; // x_int = 999 eg
return x_int + 5; // returns 1004 , violates CWE 466
}
...
int y_int = foo(); // violates CWE-466
char* y = (char*) y_int; // // well-defined but y may be invalid, violates INT36-C
char c = *y; // indeterminate value, out-of-bounds read, violates CWE-119
Bibliography
[ISO/IEC 9899:20112024] | 6.3.2.3, "Pointers" |
...