Skip to content

Commit 668f56d

Browse files
[analyzer] CStringChecker: Fix crash in CheckOverlap when arguments are not pointers (#160511)
https://github.com/llvm/llvm-project/blob/main/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp#L675-L678 mistakenly assumes that target expressions are of pointer type. `CheckOverlap` has multiple call sites, most of which do not verify this assumption. Therefore, the simplest solution is to verify it just before that point.
1 parent 41bce81 commit 668f56d

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
672672

673673
ProgramStateRef stateTrue, stateFalse;
674674

675+
if (!First.Expression->getType()->isAnyPointerType() ||
676+
!Second.Expression->getType()->isAnyPointerType())
677+
return state;
678+
675679
// Assume different address spaces cannot overlap.
676680
if (First.Expression->getType()->getPointeeType().getAddressSpace() !=
677681
Second.Expression->getType()->getPointeeType().getAddressSpace())
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_analyze_cc1 -verify %s -Wno-incompatible-library-redeclaration \
2+
// RUN: -analyzer-checker=alpha.unix.cstring.BufferOverlap
3+
// expected-no-diagnostics
4+
5+
typedef typeof(sizeof(int)) size_t;
6+
7+
void memcpy(int dst, int src, size_t size);
8+
9+
void test_memcpy_proxy() {
10+
memcpy(42, 42, 42); // no-crash
11+
}
12+
13+
void strcpy(int dst, char *src);
14+
15+
void test_strcpy_proxy() {
16+
strcpy(42, (char *)42); // no-crash
17+
}
18+
19+
void strxfrm(int dst, char *src, size_t size);
20+
21+
void test_strxfrm_proxy() {
22+
strxfrm(42, (char *)42, 42); // no-crash
23+
}

clang/test/Analysis/buffer-overlap.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,10 @@ void test_snprintf6() {
9696
char b[4] = {0};
9797
snprintf(a, sizeof(a), "%s", b); // no-warning
9898
}
99+
100+
void* memcpy(void* dest, const void* src, size_t count);
101+
102+
void test_memcpy_esoteric() {
103+
label:
104+
memcpy((char *)&&label, (const char *)memcpy, 1);
105+
}

0 commit comments

Comments
 (0)