[compiler-rt] 1293e93 - [Sanitizer] Fix page alignment for mmap calls

Blue Gaston via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 22 10:26:51 PST 2022


Author: Blue Gaston
Date: 2022-12-22T13:25:41-05:00
New Revision: 1293e93ee3da0d53665975499a909a45c5b90423

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

LOG: [Sanitizer] Fix page alignment for mmap calls

We are in the process of enabling sanitizer_common unit tests on arm64 for apple devices. rdar://101436019

The test `CompactRingBuffer.int64` is failing on arm64 with the error:

```==17265==ERROR: SanitizerTool failed to deallocate 0xfffffffffffff000 (-4096) bytes at address 0x000105c30000
SanitizerTool: CHECK failed: sanitizer_posix.cpp:63 "(("unable to unmap" && 0)) != (0)" (0x0, 0x0) (tid=157296)```

If page size is sufficiently larger than alignment then this code:
   UnmapOrDie((void*)end, map_end - end);
end is will be greater than map_end causing the value passed to UnmapOrDie to be negative.

This is caused when GetPageSizeCached returns 16k and alignment is 8k.
map_size and what is mapped by mmap uses size and alignment which is smaller than what is calculated by end using the actual page size.
Therefore, map_end ends up being less than end.
The call to mmap is allocating sufficent page-aligned memory, because it calls RoundUp within MmapOrDieOnFatalError.
But this size is not being captured by map_size.

We can address this by rounding up map_size here to be page-aligned. This ensures that map_end will be greater than or equal to end and that it will match mmaps use of page-aligned value, and the
subsequent call to munmap will also be page-aligned.

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

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
index b0e32b50c0764..75968ad33ccf5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
@@ -87,19 +87,26 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
   CHECK(IsPowerOfTwo(size));
   CHECK(IsPowerOfTwo(alignment));
   uptr map_size = size + alignment;
+  // mmap maps entire pages and rounds up map_size needs to be a an integral 
+  // number of pages. 
+  // We need to be aware of this size for calculating end and for unmapping
+  // fragments before and after the alignment region.
+  map_size = RoundUpTo(map_size, GetPageSizeCached());
   uptr map_res = (uptr)MmapOrDieOnFatalError(map_size, mem_type);
   if (UNLIKELY(!map_res))
     return nullptr;
-  uptr map_end = map_res + map_size;
   uptr res = map_res;
   if (!IsAligned(res, alignment)) {
     res = (map_res + alignment - 1) & ~(alignment - 1);
     UnmapOrDie((void*)map_res, res - map_res);
   }
+  uptr map_end = map_res + map_size;
   uptr end = res + size;
   end = RoundUpTo(end, GetPageSizeCached());
-  if (end != map_end)
+  if (end != map_end) {
+    CHECK_LT(end, map_end);
     UnmapOrDie((void*)end, map_end - end);
+  }
   return (void*)res;
 }
 


        


More information about the llvm-commits mailing list