[compiler-rt] 4db6803 - [lsan][fuchsia] Add extra check for allocator cache to avoid overflow

Leonard Chan via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 14 16:04:58 PDT 2023


Author: Leonard Chan
Date: 2023-09-14T23:03:16Z
New Revision: 4db6803dc799ae79bccef0d24484528b6bb0dcbc

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

LOG: [lsan][fuchsia] Add extra check for allocator cache to avoid overflow

Prior to this, we would check if the end of the allocator cache was located
before the end of the chunk passed to the tls check. However, if the actual
allocator cache comes after the end of the chunk, then the sub in the
`end - params->allocator_caches[i]` bit overflows. Since the resulting type
is an unsigned uptr, this is not UB, but if the signed result would be a
negative value (ie. `end < params->allocator_caches[i]`) then this will
actually result in a very large unsigned value much bigger than the compared
`sizeof(AllocatorCache)` which will almost always be true. This can cause
ScanRangeForPointers to accept incorrect values: a begin pointing to some
address, and `params->allocator_caches[i]` pointing to some much larger
address way past the end of the chunk which can result in a page fault/stack overflow.

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

Added: 
    

Modified: 
    compiler-rt/lib/lsan/lsan_common_fuchsia.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp
index 0aee77ebd53497e..cb3fe1f859f798d 100644
--- a/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp
+++ b/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp
@@ -119,6 +119,7 @@ void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
     auto i = __sanitizer::InternalLowerBound(params->allocator_caches, begin);
     if (i < params->allocator_caches.size() &&
         params->allocator_caches[i] >= begin &&
+        params->allocator_caches[i] <= end &&
         end - params->allocator_caches[i] >= sizeof(AllocatorCache)) {
       // Split the range in two and omit the allocator cache within.
       ScanRangeForPointers(begin, params->allocator_caches[i],


        


More information about the llvm-commits mailing list