Implicit pointer to integer conversion
| Vulnerability potential | Low |
| DDoS potential | None |
The pointer is implicitly casted to an integer
Impact
Implicitly converting a pointer to an integer is dangerous mainly when the
integer is narrower than the pointer. On LP64 platforms (Linux/macOS 64-bit) a
pointer is 64 bits but int and long (on Windows LLP64) are only 32, so
storing a pointer in an int discards the high half. If that integer is later
converted back to a pointer, it no longer addresses the original object — the
program dereferences a corrupted address and crashes or, worse, touches the
wrong memory. Even when the value is never converted back, comparisons and
arithmetic on the truncated integer give wrong answers. It is also a portability
trap: code that “works” on a 32-bit build silently breaks on 64-bit.
Vulnerability potential
The direct security weight is low, but truncation can seed memory-safety bugs.
- A truncated and reconstituted pointer addresses an unintended object; a write through it is effectively an out-of-bounds/arbitrary write whose target depends on the high bits that were lost.
- Storing pointers in too-narrow integers can defeat ASLR reasoning or leak partial address bits in serialized data.
- Most commonly the corrupted pointer just crashes the process (DoS-adjacent), but the underlying corruption can be steered in some layouts.
Because triggering a real exploit requires specific layout and round-tripping, the severity is low rather than high.
Technical details
C and C++ do not implicitly convert between pointers and integers without a
diagnostic (it requires a cast, and in C++ it is an error). When such a
conversion does happen — through a cast, a union, or a sloppy API — the result
is implementation-defined, and only intptr_t/uintptr_t are guaranteed wide
enough to hold a pointer round-trip.
Data-model differences
ILP32 (32-bit): int, long, pointer all 32 bits — truncation hidden. LP64
(64-bit Unix): int 32, long 64, pointer 64. LLP64 (64-bit Windows): int
and long 32, pointer 64. Code that assumed sizeof(long) == sizeof(void*)
breaks on Windows; code that used int breaks everywhere on 64-bit.
The correct types
Use uintptr_t/intptr_t (from <stdint.h>) for any integer that must hold a
pointer value, and never an int or plain long.
Catching the issue
Compiler
Build with -Wall -Wextra; GCC/Clang emit -Wint-conversion /
-Wpointer-to-int-cast and, on size mismatch, -Wint-to-pointer-cast. Promote
them with -Werror. MSVC emits C4311/C4312 for pointer truncation. In C++ the
implicit conversion is simply rejected.
Static analysis
Clang-tidy (cppcoreguidelines-pro-type-reinterpret-cast,
bugprone-*), Coverity, Cppcheck, and PVS-Studio flag narrowing
pointer-to-integer conversions.
Review
Whenever a pointer must live in an integer (tagging, hashing, FFI), require
uintptr_t and an explicit cast, and document the round-trip.
How to reproduce
Compile for 64-bit with -Wall; observe the warning and that the reconstructed
pointer differs from the original because the high 32 bits were lost.
#include <stdio.h>
int main(void)
{
int x = 42;
int *p = &x;
int truncated = (int)(long)p; /* pointer squeezed into 32-bit int */
int *q = (int *)(long)truncated;
printf("orig=%p round-trip=%p equal=%d\n",
(void *)p, (void *)q, p == q); /* not equal on LP64/LLP64 */
return 0;
}