[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