forked from OSchip/llvm-project
[asan] Fix bug where suppression of overlapping accesses was ignored on
`strcpy()`, `strncpy()`, `strcat()`, and `strncat()`. rdar://problem/35576899 Differential Revision: https://reviews.llvm.org/D43702 llvm-svn: 327068
This commit is contained in:
parent
70e6faaa0d
commit
0faaa99e4d
|
@ -133,15 +133,22 @@ static inline bool RangesOverlap(const char *offset1, uptr length1,
|
|||
const char *offset2, uptr length2) {
|
||||
return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
|
||||
}
|
||||
#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
|
||||
const char *offset1 = (const char*)_offset1; \
|
||||
const char *offset2 = (const char*)_offset2; \
|
||||
if (RangesOverlap(offset1, length1, offset2, length2)) { \
|
||||
GET_STACK_TRACE_FATAL_HERE; \
|
||||
ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
|
||||
offset2, length2, &stack); \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) \
|
||||
do { \
|
||||
const char *offset1 = (const char *)_offset1; \
|
||||
const char *offset2 = (const char *)_offset2; \
|
||||
if (RangesOverlap(offset1, length1, offset2, length2)) { \
|
||||
GET_STACK_TRACE_FATAL_HERE; \
|
||||
bool suppressed = IsInterceptorSuppressed(name); \
|
||||
if (!suppressed && HaveStackTraceBasedSuppressions()) { \
|
||||
suppressed = IsStackTraceSuppressed(&stack); \
|
||||
} \
|
||||
if (!suppressed) { \
|
||||
ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
|
||||
offset2, length2, &stack); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O1 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O2 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O3 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Don't inline function otherwise stacktrace changes.
|
||||
__attribute__((noinline)) void bad_function() {
|
||||
char buffer[] = "hello\0XXX";
|
||||
// CHECK: strcat-param-overlap: memory ranges
|
||||
// CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
|
||||
// CHECK: {{#0 0x.* in .*strcat}}
|
||||
// CHECK: {{#1 0x.* in bad_function.*strcat-overlap.cc:}}[[@LINE+2]]
|
||||
// CHECK: {{#2 0x.* in main .*strcat-overlap.cc:}}[[@LINE+5]]
|
||||
strcat(buffer, buffer + 1); // BOOM
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bad_function();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O1 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O2 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O3 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strcpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Don't inline function otherwise stacktrace changes.
|
||||
__attribute__((noinline)) void bad_function() {
|
||||
char buffer[] = "hello";
|
||||
// CHECK: strcpy-param-overlap: memory ranges
|
||||
// CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
|
||||
// CHECK: {{#0 0x.* in .*strcpy}}
|
||||
// CHECK: {{#1 0x.* in bad_function.*strcpy-overlap.cc:}}[[@LINE+2]]
|
||||
// CHECK: {{#2 0x.* in main .*strcpy-overlap.cc:}}[[@LINE+5]]
|
||||
strcpy(buffer, buffer + 1); // BOOM
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bad_function();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O1 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O2 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O3 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncat" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Don't inline function otherwise stacktrace changes.
|
||||
__attribute__((noinline)) void bad_function() {
|
||||
char buffer[] = "hello\0XXX";
|
||||
// CHECK: strncat-param-overlap: memory ranges
|
||||
// CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
|
||||
// CHECK: {{#0 0x.* in .*strncat}}
|
||||
// CHECK: {{#1 0x.* in bad_function.*strncat-overlap.cc:}}[[@LINE+2]]
|
||||
// CHECK: {{#2 0x.* in main .*strncat-overlap.cc:}}[[@LINE+5]]
|
||||
strncat(buffer, buffer + 1, 3); // BOOM
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bad_function();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O1 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O2 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
//
|
||||
// RUN: %clangxx_asan -O3 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
// RUN: echo "interceptor_name:strncpy" > %t.supp
|
||||
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Don't inline function otherwise stacktrace changes.
|
||||
__attribute__((noinline)) void bad_function() {
|
||||
char buffer[] = "hello";
|
||||
// CHECK: strncpy-param-overlap: memory ranges
|
||||
// CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
|
||||
// CHECK: {{#0 0x.* in .*strncpy}}
|
||||
// CHECK: {{#1 0x.* in bad_function.*strncpy-overlap.cc:}}[[@LINE+2]]
|
||||
// CHECK: {{#2 0x.* in main .*strncpy-overlap.cc:}}[[@LINE+5]]
|
||||
strncpy(buffer, buffer + 1, 5); // BOOM
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bad_function();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue