[compiler-rt] ad1dd78 - [hwasan] Fixup mmap tagging regions

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 14 15:32:18 PDT 2023


Author: Vitaly Buka
Date: 2023-06-14T15:32:12-07:00
New Revision: ad1dd78793263b34e33b469f67e2012092231fbc

URL: https://github.com/llvm/llvm-project/commit/ad1dd78793263b34e33b469f67e2012092231fbc
DIFF: https://github.com/llvm/llvm-project/commit/ad1dd78793263b34e33b469f67e2012092231fbc.diff

LOG: [hwasan] Fixup mmap tagging regions

Reviewed By: thurston

Differential Revision: https://reviews.llvm.org/D152893

Added: 
    

Modified: 
    compiler-rt/lib/hwasan/hwasan_interceptors.cpp
    compiler-rt/test/hwasan/TestCases/munmap.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
index c8e9a128d08b9..fab21b2e85a78 100644
--- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp
@@ -184,8 +184,9 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
   }
   SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
   void *end_addr = (char *)addr + (rounded_length - 1);
-  if (addr && (!MemIsApp(reinterpret_cast<uptr>(addr)) ||
-               !MemIsApp(reinterpret_cast<uptr>(end_addr)))) {
+  if (addr && length &&
+      (!MemIsApp(reinterpret_cast<uptr>(addr)) ||
+       !MemIsApp(reinterpret_cast<uptr>(end_addr)))) {
     // User requested an address that is incompatible with HWASan's
     // memory layout. Use a 
diff erent address if allowed, else fail.
     if (flags & map_fixed) {
@@ -196,17 +197,17 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
     }
   }
   void *res = real_mmap(addr, length, prot, flags, fd, offset);
-  if (res != (void *)-1) {
-    void *end_res = (char *)res + (rounded_length - 1);
-    if (!MemIsApp(reinterpret_cast<uptr>(res)) ||
-        !MemIsApp(reinterpret_cast<uptr>(end_res))) {
+  if (length && res != (void *)-1) {
+    uptr beg = reinterpret_cast<uptr>(res);
+    DCHECK(IsAligned(beg, GetPageSize()));
+    if (!MemIsApp(beg) || !MemIsApp(beg + rounded_length - 1)) {
       // Application has attempted to map more memory than is supported by
       // HWASan. Act as if we ran out of memory.
       internal_munmap(res, length);
       errno = errno_ENOMEM;
       return (void *)-1;
     }
-    __hwasan::TagMemory(reinterpret_cast<uptr>(addr), length, 0);
+    __hwasan::TagMemoryAligned(beg, rounded_length, 0);
   }
 
   return res;
@@ -214,7 +215,18 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
 
 template <class Munmap>
 static int munmap_interceptor(Munmap real_munmap, void *addr, SIZE_T length) {
-  __hwasan::TagMemory(reinterpret_cast<uptr>(addr), length, 0);
+  // We should not tag if munmap fail, but it's to late to tag after
+  // real_munmap, as the pages could be mmaped by another thread.
+  uptr beg = reinterpret_cast<uptr>(addr);
+  if (length && IsAligned(beg, GetPageSize())) {
+    SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
+    // Protect from unmapping the shadow.
+    if (!MemIsApp(beg) || !MemIsApp(beg + rounded_length - 1)) {
+      errno = errno_EINVAL;
+      return -1;
+    }
+    __hwasan::TagMemoryAligned(beg, rounded_length, 0);
+  }
   return real_munmap(addr, length);
 }
 

diff  --git a/compiler-rt/test/hwasan/TestCases/munmap.c b/compiler-rt/test/hwasan/TestCases/munmap.c
index 6f8f97b675566..01aa90dfcad88 100644
--- a/compiler-rt/test/hwasan/TestCases/munmap.c
+++ b/compiler-rt/test/hwasan/TestCases/munmap.c
@@ -1,5 +1,6 @@
 // RUN: %clang_hwasan  %s -o %t
-// RUN: %run %t 2>&1
+// RUN: %run %t 1 2>&1
+// RUN: %run %t 2 2>&1
 
 // REQUIRES: pointer-tagging
 
@@ -7,9 +8,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
+#include <unistd.h>
 
 int main(int argc, char **argv) {
-  const int kSize = 4096;
+  const size_t kPS = sysconf(_SC_PAGESIZE);
+  const int kSize = kPS / atoi(argv[1]);
   const int kTag = 47;
 
   // Get any mmaped pointer.
@@ -27,26 +30,36 @@ int main(int argc, char **argv) {
   }
 
   // Manually tag the pointer and the memory.
-  __hwasan_tag_memory(r, kTag, kSize);
+  __hwasan_tag_memory(r, kTag, kPS);
   int *p1 = __hwasan_tag_pointer(r, kTag);
 
   // Check that the pointer and the tag match.
-  if (__hwasan_test_shadow(p1, kSize) != -1) {
+  if (__hwasan_test_shadow(p1, kPS) != -1) {
     fprintf(stderr, "Failed to tag.\n");
     abort();
   }
 
+  if (munmap((char *)r + 1, kSize) == 0) {
+    perror("munmap should fail: ");
+    abort();
+  }
+
+  if (__hwasan_test_shadow(p1, kPS) != -1) {
+    fprintf(stderr, "Still must be tagged.\n");
+    abort();
+  }
+
   // First munmmap and then mmap the same pointer using MAP_FIXED.
   if (munmap((char *)r, kSize) != 0) {
     perror("Failed to unmap: ");
     abort();
   }
 
-  if (__hwasan_test_shadow(r, kSize) != -1) {
+  if (__hwasan_test_shadow(r, kPS) != -1) {
     fprintf(stderr, "Shadow memory was not cleaned by munmap.\n");
     abort();
   }
-  __hwasan_tag_memory(r, kTag, kSize);
+  __hwasan_tag_memory(r, kTag, kPS);
   int *p2 = (int *)mmap(r, kSize, PROT_READ | PROT_WRITE,
                         MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
 
@@ -57,7 +70,7 @@ int main(int argc, char **argv) {
   }
 
   // Make sure we can access the shadow with an untagged pointer.
-  if (__hwasan_test_shadow(p2, kSize) != -1) {
+  if (__hwasan_test_shadow(p2, kPS) != -1) {
     fprintf(stderr, "Shadow memory was not cleaned by mmap.\n");
     abort();
   }


        


More information about the llvm-commits mailing list