Skip to content

Add check: invalidPointerOverlapTest for unsafe pointer overflow comparison#8620

Draft
tmleman wants to merge 1 commit into
cppcheck-opensource:mainfrom
tmleman:topic/checkcondition/new/pointer_overflow
Draft

Add check: invalidPointerOverlapTest for unsafe pointer overflow comparison#8620
tmleman wants to merge 1 commit into
cppcheck-opensource:mainfrom
tmleman:topic/checkcondition/new/pointer_overflow

Conversation

@tmleman
Copy link
Copy Markdown

@tmleman tmleman commented Jun 2, 2026

Add a new inconclusive warning that detects the pointer overlap idiom

p1 >= p2 && p1 < p2 + n        (or its mirror / cast variants)

where p1 and p2 are distinct pointers and n is an unsigned offset, e.g. the memcpy_s overlap check '(dest >= src && dest < src + count) || ...'.

The 'p1 < p2 + n' clause assumes 'p2 + n' does not overflow past the end of the object. If n is large enough that 'p2 + n' wraps (UB), some mainstream compilers assume the wrap cannot happen and fold the comparison, silently dropping the check. The remedy in user code is to cast the pointers to uintptr_t and compare in integer space, with an explicit overflow guard.

To avoid false positives, the warning only fires when the comparison is paired (via &&) with another comparison of the same two pointers, which identifies the overlap idiom; plain bounds checks like 'p < buf + len' and room checks like 'cur + need <= limit' are not flagged. The check is gated behind --enable=inconclusive. The same-pointer case 'p < p + n' is left to the existing invalidTestForOverflow check.

This pattern was found in a real memcpy_s overlap check via fuzzing with UndefinedBehaviorSanitizer; the check is added so similar issues can be caught statically in the future.

@tmleman tmleman force-pushed the topic/checkcondition/new/pointer_overflow branch from fcbffc1 to 8d9b4ba Compare June 2, 2026 20:27
…arison

Add a new inconclusive warning that detects the pointer overlap idiom

    p1 >= p2 && p1 < p2 + n        (or its mirror / cast variants)

where p1 and p2 are distinct pointers and n is an unsigned offset, e.g.
the memcpy_s overlap check '(dest >= src && dest < src + count) || ...'.

The 'p1 < p2 + n' clause assumes 'p2 + n' does not overflow past the end
of the object. If n is large enough that 'p2 + n' wraps (UB), some
mainstream compilers assume the wrap cannot happen and fold the
comparison, silently dropping the check. The remedy in user code is to
cast the pointers to uintptr_t and compare in integer space, with an
explicit overflow guard.

To avoid false positives, the warning only fires when the comparison is
paired (via &&) with another comparison of the same two pointers, which
identifies the overlap idiom; plain bounds checks like 'p < buf + len'
and room checks like 'cur + need <= limit' are not flagged. The check is
gated behind --enable=inconclusive. The same-pointer case 'p < p + n' is
left to the existing invalidTestForOverflow check.

This pattern was found in a real memcpy_s overlap check via fuzzing with
UndefinedBehaviorSanitizer; the check is added so similar issues can be
caught statically in the future.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant