Index: lib/msan/msan_interceptors.cc =================================================================== --- lib/msan/msan_interceptors.cc +++ lib/msan/msan_interceptors.cc @@ -178,10 +178,6 @@ return __msan_memset(s, c, n); } -INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) { - return __msan_memmove(dest, src, n); -} - INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) { GET_MALLOC_STACK_TRACE; CHECK_EQ(alignment & (alignment - 1), 0); @@ -1519,7 +1515,6 @@ INTERCEPT_FUNCTION(mempcpy); INTERCEPT_FUNCTION(memset); INTERCEPT_FUNCTION(memmove); - INTERCEPT_FUNCTION(bcopy); INTERCEPT_FUNCTION(wmemset); INTERCEPT_FUNCTION(wmemcpy); INTERCEPT_FUNCTION(wmempcpy); Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -4906,6 +4906,39 @@ #define INIT___BZERO #endif // SANITIZER_INTERCEPT___BZERO +#if SANITIZER_INTERCEPT_BZERO +DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr) + +INTERCEPTOR(void, bzero, void *block, uptr size) { + WRAP(memset)(block, 0, size); +} +#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero); +#else +#define INIT_BZERO +#endif // SANITIZER_INTERCEPT_BZERO + +#if SANITIZER_INTERCEPT_BCOPY +DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr) + +INTERCEPTOR(void, bcopy, const void *src, void *dest, uptr size) { + WRAP(memmove)(dest, src, size); +} +#define INIT_BCOPY COMMON_INTERCEPT_FUNCTION(bcopy); +#else +#define INIT_BCOPY +#endif // SANITIZER_INTERCEPT_BCOPY + +#if SANITIZER_INTERCEPT_BCMP +DECLARE_REAL_AND_INTERCEPTOR(int, memcmp, const void *, const void *, uptr) + +INTERCEPTOR(int, bcmp, const void *s1, const void *s2, uptr size) { + return WRAP(memcmp)(s1, s2, size); +} +#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp); +#else +#define INIT_BCMP +#endif // SANITIZER_INTERCEPT_BCMP + #if SANITIZER_INTERCEPT_FTIME INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { void *ctx; @@ -6056,6 +6089,9 @@ INIT_CAPGET; INIT_AEABI_MEM; INIT___BZERO; + INIT_BZERO; + INIT_BCOPY; + INIT_BCMP; INIT_FTIME; INIT_XDR; INIT_TSEARCH; Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -274,6 +274,11 @@ #define SANITIZER_INTERCEPT_AEABI_MEM 0 #endif #define SANITIZER_INTERCEPT___BZERO SI_MAC +// TODO(kuba.brecka): Add SI_MAC when strncpy on Darwin supports bzero +// interceptors. https://reviews.llvm.org/D27659. +#define SANITIZER_INTERCEPT_BZERO SI_LINUX || SI_FREEBSD +#define SANITIZER_INTERCEPT_BCOPY SI_LINUX || SI_FREEBSD || SI_MAC +#define SANITIZER_INTERCEPT_BCMP SI_LINUX || SI_FREEBSD || SI_MAC #define SANITIZER_INTERCEPT_FTIME !SI_FREEBSD && SI_NOT_WINDOWS #define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_TSEARCH SI_LINUX_NOT_ANDROID || SI_MAC Index: test/asan/TestCases/Linux/bcmp_test.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Linux/bcmp_test.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=A1 +// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=A2 +// RUN: %env_asan_opts=intercept_memcmp=0 %run %t + +#include +int main(int argc, char **argv) { + char a1[] = {1, 2, 3, 4, 5, 6, 7, 8}; + char a2[] = {3, 4, 5, 6, 7, 8, 9}; + int res; + if (argc == 1) + res = bcmp(a1, a2, sizeof(a1)); // BOOM + else + res = bcmp(a2, a1, sizeof(a1)); // BOOM + // A1: AddressSanitizer: stack-buffer-overflow + // A1: {{#0.*memcmp}} + // A1: 'a2' <== Memory access at offset + // + // A2: AddressSanitizer: stack-buffer-overflow + // A2: {{#0.*memcmp}} + // A2: 'a2' <== Memory access at offset + return res == 0; +} Index: test/asan/TestCases/Linux/bcopy_test.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Linux/bcopy_test.cc @@ -0,0 +1,22 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=A1 +// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=A2 +// RUN: %env_asan_opts=replace_intrin=0 %run %t + +#include +int main(int argc, char **argv) { + char a1[] = {1, 2, 3, 4, 5, 6, 7, 8}; + char a2[] = {3, 4, 5, 6, 7, 8, 9}; + if (argc == 1) + bcopy(a1, a2, sizeof(a1)); // BOOM + else + bcopy(a2, a1, sizeof(a1)); // BOOM + // A1: AddressSanitizer: stack-buffer-overflow + // A1: {{#0.*memmove}} + // A1: 'a2' <== Memory access at offset + // + // A2: AddressSanitizer: stack-buffer-overflow + // A2: {{#0.*memmove}} + // A2: 'a2' <== Memory access at offset + return 0; +} Index: test/asan/TestCases/Linux/bzero_test.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Linux/bzero_test.cc @@ -0,0 +1,13 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=A1 +// RUN: %env_asan_opts=replace_intrin=0 %run %t + +#include +int main(int argc, char **argv) { + char a1[] = {1, 2, 3, 4, 5, 6, 7, 8}; + bzero(a1, sizeof(a1) + 1); // BOOM + // A1: AddressSanitizer: stack-buffer-overflow + // A1: {{#0.*memset}} + // A1: 'a1' <== Memory access at offset + return 0; +}