Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Updated references from C11->C23

...

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 [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
langc

...

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.

...

CERT_C-INT36-aAn object with integer type or pointer to void type shall not be converted to an object with pointer type

Unsafe conversion between pointer and integer

MISRA 2012 Rule 11.6Misaligned or invalid results from conversions types

A cast shall not be performed between pointer to void and an arithmetic type

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

pointer-integral-cast

pointer-integral-cast-implicit

function-pointer-integer-cast

function-pointer-integer-cast-implicit

Fully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-INT36Fully implemented
Clang
Include Page
Clang_V
Clang_V
-Wint-to-pointer-cast, -Wint-conversionCan detect some instances of this rule, but does not detect all
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
LANG.CAST.PC.CONST2PTR
LANG.CAST.PC.INT
Conversion: integer constant to pointer
Conversion: pointer/integer
Compass/ROSE


Coverity
Include Page
Coverity_V
Coverity_V
PW.POINTER_CONVERSION_LOSES_BITSFully implemented
Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-int36-cPartially implemented
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

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
Include Page
Klocwork_V
Klocwork_V
MISRA.CAST.OBJ_PTR_TO_INT.2012
LDRA tool suite
Include Page
LDRA_V
LDRA_V

439 S, 440 S

Fully implemented
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

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

Include Page
PC-lint Plus_V
PC-lint Plus_V

4287

Partially supported: reports casts from pointer types to smaller integer types which lose information

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C:

Rule INT36-C


Checks for unsafe conversion between pointer and integer

(rule partially covered)

PRQA QA-C
Include Page
PRQA QA-C_vPRQA QA-C_v305, 306, 309, 429, 432, 557, 563, 671, 674Partially implementedPVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V527, V528V542, V566, V601V647, V1091
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V

pointer-integral-cast

pointer-integral-cast-implicit

function-pointer-integer-cast

function-pointer-integer-cast-implicit

Fully checked
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S1767Partially implemented

Related Vulnerabilities

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

...

Taxonomy

Taxonomy item

Relationship

CERT CINT11-CPP. Take care when converting from pointer to integer or integer to pointerPrior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TR 24772:2013Pointer Casting and Pointer Type Changes [HFC]Prior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TS 17961:2013Converting a pointer to integer or integer to pointer [intptrconv]Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-587, Assignment of a Fixed Address to a Pointer2017-07-07: CERT: Partial overlap
CWE 2.11CWE-7042017-06-14: CERT: Rule subset of CWE
CWE 2.11CWE-7582017-07-07: CERT: Rule subset of CWE
CWE 3.1CWE-119, Improper Restriction of Operations within the Bounds of a Memory Buffer2018-10-19:CERT:None
CWE 3.1CWE-466, Return of Pointer Value Outside of Expected Range2018-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"


...