[compiler-rt] r355204 - Reland "[compiler-rt] Intercept the bcmp() function."
Clement Courbet via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 1 08:42:08 PST 2019
Author: courbet
Date: Fri Mar 1 08:42:08 2019
New Revision: 355204
URL: http://llvm.org/viewvc/llvm-project?rev=355204&view=rev
Log:
Reland "[compiler-rt] Intercept the bcmp() function."
Fix test issues on darwin: The REQUIRES for the test should be the same as the
guard for whether we intercept bcmp.
Added:
compiler-rt/trunk/test/asan/TestCases/Posix/bcmp_test.cc
- copied, changed from r355203, compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc
Modified:
compiler-rt/trunk/lib/asan/tests/asan_mem_test.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc
compiler-rt/trunk/test/msan/memcmp_test.cc
compiler-rt/trunk/test/msan/scoped-interceptors.cc
compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/weak_hook_test.cc
Modified: compiler-rt/trunk/lib/asan/tests/asan_mem_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_mem_test.cc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_mem_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_mem_test.cc Fri Mar 1 08:42:08 2019
@@ -9,7 +9,11 @@
// This file is a part of AddressSanitizer, an address sanity checker.
//
//===----------------------------------------------------------------------===//
+#include <string.h>
#include "asan_test_utils.h"
+#if defined(_GNU_SOURCE)
+#include <strings.h> // for bcmp
+#endif
#include <vector>
template<typename T>
@@ -205,37 +209,43 @@ TEST(AddressSanitizer, MemMoveOOBTest) {
MemTransferOOBTestTemplate<int, MemMoveWrapper>(1024);
}
-
-TEST(AddressSanitizer, MemCmpOOBTest) {
+template <int (*cmpfn)(const void *, const void *, size_t)>
+void CmpOOBTestCommon() {
size_t size = Ident(100);
char *s1 = MallocAndMemsetString(size);
char *s2 = MallocAndMemsetString(size);
- // Normal memcmp calls.
- Ident(memcmp(s1, s2, size));
- Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));
- Ident(memcmp(s1 - 1, s2 - 1, 0));
+ // Normal cmpfn calls.
+ Ident(cmpfn(s1, s2, size));
+ Ident(cmpfn(s1 + size - 1, s2 + size - 1, 1));
+ Ident(cmpfn(s1 - 1, s2 - 1, 0));
// One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
+ EXPECT_DEATH(Ident(cmpfn)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
+ EXPECT_DEATH(Ident(cmpfn)(s1 + size, s2, 1), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1, s2 + size, 1), RightOOBReadMessage(0));
// Hit unallocated memory and die.
- EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
// Zero bytes are not terminators and don't prevent from OOB.
s1[size - 1] = '\0';
s2[size - 1] = '\0';
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1, s2, size + 1), RightOOBReadMessage(0));
// Even if the buffers differ in the first byte, we still assume that
- // memcmp may access the whole buffer and thus reporting the overflow here:
+ // cmpfn may access the whole buffer and thus reporting the overflow here:
s1[0] = 1;
s2[0] = 123;
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
+ EXPECT_DEATH(Ident(cmpfn)(s1, s2, size + 1), RightOOBReadMessage(0));
free(s1);
free(s2);
}
+TEST(AddressSanitizer, MemCmpOOBTest) { CmpOOBTestCommon<memcmp>(); }
-
+TEST(AddressSanitizer, BCmpOOBTest) {
+#if (defined(__linux__) && !defined(__ANDROID__) && defined(_GNU_SOURCE)) || \
+ defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ CmpOOBTestCommon<bcmp>();
+#endif
+}
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Fri Mar 1 08:42:08 2019
@@ -819,16 +819,14 @@ INTERCEPTOR(void *, memcpy, void *dst, c
#endif
#if SANITIZER_INTERCEPT_MEMCMP
-
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
const void *s1, const void *s2, uptr n,
int result)
-INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
- if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
- return internal_memcmp(a1, a2, size);
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
+// Common code for `memcmp` and `bcmp`.
+int MemcmpInterceptorCommon(void *ctx,
+ int (*real_fn)(const void *, const void *, uptr),
+ const void *a1, const void *a2, uptr size) {
if (common_flags()->intercept_memcmp) {
if (common_flags()->strict_memcmp) {
// Check the entire regions even if the first bytes of the buffers are
@@ -854,17 +852,39 @@ INTERCEPTOR(int, memcmp, const void *a1,
return r;
}
}
- int result = REAL(memcmp(a1, a2, size));
+ int result = real_fn(a1, a2, size);
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
a2, size, result);
return result;
}
+INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_memcmp(a1, a2, size);
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
+ return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
+}
+
#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
#else
#define INIT_MEMCMP
#endif
+#if SANITIZER_INTERCEPT_BCMP
+INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) {
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_memcmp(a1, a2, size);
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
+ return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
+}
+
+#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
+#else
+#define INIT_BCMP
+#endif
+
#if SANITIZER_INTERCEPT_MEMCHR
INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
@@ -9492,6 +9512,7 @@ static void InitializeCommonInterceptors
INIT_MEMCPY;
INIT_MEMCHR;
INIT_MEMCMP;
+ INIT_BCMP;
INIT_MEMRCHR;
INIT_MEMMEM;
INIT_READ;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Fri Mar 1 08:42:08 2019
@@ -142,6 +142,9 @@
#define SANITIZER_INTERCEPT_MEMMOVE 1
#define SANITIZER_INTERCEPT_MEMCPY 1
#define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
+#define SANITIZER_INTERCEPT_BCMP \
+ SANITIZER_INTERCEPT_MEMCMP && \
+ ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_STRNDUP SI_POSIX
#define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
Copied: compiler-rt/trunk/test/asan/TestCases/Posix/bcmp_test.cc (from r355203, compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/bcmp_test.cc?p2=compiler-rt/trunk/test/asan/TestCases/Posix/bcmp_test.cc&p1=compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc&r1=355203&r2=355204&rev=355204&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/bcmp_test.cc Fri Mar 1 08:42:08 2019
@@ -3,15 +3,16 @@
// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
-// REQUIRES: compiler-rt-optimized
+// REQUIRES: compiler-rt-optimized, (linux && !android) || openbsd || freebsd || netbsd
+// XFAIL: darwin
#include <string.h>
int main(int argc, char **argv) {
char a1[] = {static_cast<char>(argc), 2, 3, 4};
- char a2[] = {1, static_cast<char>(2*argc), 3, 4};
- int res = memcmp(a1, a2, 4 + argc); // BOOM
+ char a2[] = {1, static_cast<char>(2 * argc), 3, 4};
+ int res = bcmp(a1, a2, 4 + argc); // BOOM
// CHECK: AddressSanitizer: stack-buffer-overflow
- // CHECK: {{#0.*memcmp}}
- // CHECK: {{#1.*main}}
+ // CHECK: {{#1.*bcmp}}
+ // CHECK: {{#2.*main}}
return res;
}
Modified: compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/memcmp_test.cc Fri Mar 1 08:42:08 2019
@@ -11,7 +11,7 @@ int main(int argc, char **argv) {
char a2[] = {1, static_cast<char>(2*argc), 3, 4};
int res = memcmp(a1, a2, 4 + argc); // BOOM
// CHECK: AddressSanitizer: stack-buffer-overflow
- // CHECK: {{#0.*memcmp}}
- // CHECK: {{#1.*main}}
+ // CHECK: {{#1.*memcmp}}
+ // CHECK: {{#2.*main}}
return res;
}
Modified: compiler-rt/trunk/test/msan/memcmp_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/memcmp_test.cc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/test/msan/memcmp_test.cc (original)
+++ compiler-rt/trunk/test/msan/memcmp_test.cc Fri Mar 1 08:42:08 2019
@@ -13,6 +13,6 @@ int main(int argc, char **argv) {
if (!res)
printf("equals");
return 0;
- // CHECK: Uninitialized bytes in __interceptor_memcmp at offset 3
+ // CHECK: Uninitialized bytes in MemcmpInterceptorCommon at offset 3
// CHECK: MemorySanitizer: use-of-uninitialized-value
}
Modified: compiler-rt/trunk/test/msan/scoped-interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/scoped-interceptors.cc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/test/msan/scoped-interceptors.cc (original)
+++ compiler-rt/trunk/test/msan/scoped-interceptors.cc Fri Mar 1 08:42:08 2019
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {
case '2': {
int cmp = memcmp(uninit, uninit, sizeof(uninit)); // BOOM
break;
- // CASE-2: Uninitialized bytes in __interceptor_memcmp
+ // CASE-2: Uninitialized bytes in MemcmpInterceptorCommon
}
case '3': {
size_t len = strlen(uninit); // BOOM
Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/weak_hook_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/weak_hook_test.cc?rev=355204&r1=355203&r2=355204&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/weak_hook_test.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/weak_hook_test.cc Fri Mar 1 08:42:08 2019
@@ -6,8 +6,11 @@
// XFAIL: lsan
// XFAIL: ubsan
-#include <string.h>
#include <assert.h>
+#include <string.h>
+#if defined(_GNU_SOURCE)
+#include <strings.h> // for bcmp
+#endif
bool seen_memcmp, seen_strncmp, seen_strncasecmp, seen_strcmp, seen_strcasecmp,
seen_strstr, seen_strcasestr, seen_memmem;
@@ -59,6 +62,12 @@ int main() {
int_sink = memcmp(s1, s2, sizeof(s2));
assert(seen_memcmp);
+#if (defined(__linux__) && !defined(__ANDROID__) && defined(_GNU_SOURCE)) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ seen_memcmp = false;
+ int_sink = bcmp(s1, s2, sizeof(s2));
+ assert(seen_memcmp);
+#endif
+
int_sink = strncmp(s1, s2, sizeof(s2));
assert(seen_strncmp);
More information about the llvm-commits
mailing list