[compiler-rt] [HWASAN] Add memset interceptor (PR #71244)

Kirill Stoimenov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 6 17:06:02 PST 2023


https://github.com/kstoimenov updated https://github.com/llvm/llvm-project/pull/71244

>From 49eb09532434705e896050c52a75c70b71d0c59b Mon Sep 17 00:00:00 2001
From: Kirill Stoimenov <kstoimenov at google.com>
Date: Fri, 3 Nov 2023 21:08:12 +0000
Subject: [PATCH 1/2] [HWASAN] Add memset interceptor

---
 .../lib/hwasan/hwasan_interceptors.cpp        | 12 +++----
 .../lib/hwasan/hwasan_platform_interceptors.h |  4 +--
 ...izer_common_interceptors_memintrinsics.inc |  6 ++++
 compiler-rt/test/hwasan/TestCases/memset.cpp  | 32 +++++++++++++++++++
 4 files changed, 44 insertions(+), 10 deletions(-)
 create mode 100644 compiler-rt/test/hwasan/TestCases/memset.cpp

diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
index 1a77d776e65e4ba..5bd94fb36c502c4 100644
--- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
@@ -19,6 +19,7 @@
 #include "hwasan.h"
 #include "hwasan_allocator.h"
 #include "hwasan_checks.h"
+#include "hwasan_mapping.h"
 #include "hwasan_platform_interceptors.h"
 #include "hwasan_thread.h"
 #include "hwasan_thread_list.h"
@@ -146,14 +147,6 @@ struct HWAsanInterceptorContext {
         (void)(name);                           \
       } while (false)
 
-#    define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
-      do {                                                      \
-        (void)(ctx);                                            \
-        (void)(block);                                          \
-        (void)(c);                                              \
-        (void)(size);                                           \
-      } while (false)
-
 #    define COMMON_INTERCEPTOR_STRERROR() \
       do {                                \
       } while (false)
@@ -162,6 +155,9 @@ struct HWAsanInterceptorContext {
 
 #    define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!hwasan_inited)
 
+#    define COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW(p) \
+  MemIsShadow(reinterpret_cast<uptr>(p))
+
 // The main purpose of the mmap interceptor is to prevent the user from
 // allocating on top of shadow pages.
 //
diff --git a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
index e31ee9e406c67e3..d92b51052194275 100644
--- a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
+++ b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
@@ -56,8 +56,8 @@
 #undef SANITIZER_INTERCEPT_STRCASECMP
 #define SANITIZER_INTERCEPT_STRCASECMP 0
 
-#undef SANITIZER_INTERCEPT_MEMSET
-#define SANITIZER_INTERCEPT_MEMSET 0
+// #undef SANITIZER_INTERCEPT_MEMSET
+// #define SANITIZER_INTERCEPT_MEMSET 0
 
 // #undef SANITIZER_INTERCEPT_MEMMOVE
 // #define SANITIZER_INTERCEPT_MEMMOVE 0
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
index 52e489d02cda83e..fca73712483c028 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
@@ -40,11 +40,17 @@
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
 #endif  // SANITIZER_APPLE
 
+#ifndef COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW
+#define COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW(p) (0)
+#endif
+
 #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
   {                                                       \
     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)        \
       return internal_memset(dst, v, size);               \
+    if (COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW(dst))   \
+      return internal_memset(dst, v, size);               \
     COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);  \
     if (common_flags()->intercept_intrin)                 \
       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);     \
diff --git a/compiler-rt/test/hwasan/TestCases/memset.cpp b/compiler-rt/test/hwasan/TestCases/memset.cpp
new file mode 100644
index 000000000000000..ae31a3bfe9cdaa4
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/memset.cpp
@@ -0,0 +1,32 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_hwasan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_hwasan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_hwasan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/hwasan_interface.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+__attribute__((no_sanitize("hwaddress"))) void
+ForceCallInterceptor(void *p, int c, size_t size) {
+  memset(p, c, size) == nullptr;
+}
+
+int main(int argc, char **argv) {
+  __hwasan_enable_allocator_tagging();
+  char a[] = {static_cast<char>(argc), 2, 3, 4};
+  int size = sizeof(a);
+  char *volatile p = (char *)malloc(size);
+  free(p);
+  ForceCallInterceptor(p, 0, size);
+  return 0;
+  // CHECK: HWAddressSanitizer: tag-mismatch on address
+  // CHECK: WRITE of size 4
+  // CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memset.cpp:[[@LINE-4]]
+  // CHECK: Cause: use-after-free
+  // CHECK: freed by thread
+  // CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memset.cpp:[[@LINE-8]]
+  // CHECK: previously allocated by thread
+  // CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memset.cpp:[[@LINE-11]]
+}

>From a7ac1f32c6556613123b65f43271d5b8c5e9e42c Mon Sep 17 00:00:00 2001
From: Kirill Stoimenov <kstoimenov at google.com>
Date: Tue, 7 Nov 2023 01:04:47 +0000
Subject: [PATCH 2/2] Fix COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW to use
 MemIsApp with untagged pointer

---
 compiler-rt/lib/hwasan/hwasan_interceptors.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
index 5bd94fb36c502c4..412cf8c8ec1fd52 100644
--- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
@@ -156,7 +156,7 @@ struct HWAsanInterceptorContext {
 #    define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!hwasan_inited)
 
 #    define COMMON_INTERCEPTOR_MEMSET_CHECK_IN_SHADOW(p) \
-  MemIsShadow(reinterpret_cast<uptr>(p))
+  (!MemIsApp(UntagAddr(reinterpret_cast<uptr>(p))))
 
 // The main purpose of the mmap interceptor is to prevent the user from
 // allocating on top of shadow pages.



More information about the llvm-commits mailing list