[compiler-rt] 6f48065 - [ASan][Darwin] Avoid crash during ASan initialization

Julian Lettner via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 7 12:28:45 PST 2022


Author: Julian Lettner
Date: 2022-01-07T12:28:38-08:00
New Revision: 6f480655e69a4ae0b1d4c3d749cece2716a6f43c

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

LOG: [ASan][Darwin] Avoid crash during ASan initialization

Always pass `depth=1` to `vm_region_recurse_64()`.  `depth` is a in-out
parameter and gets reset to 0 after the first call, so we incorrectly
pass `depth=0` on subsequent calls.

We want to avoid the following crash:
```
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000180000000
Exception Codes: 0x0000000000000001, 0x0000000180000000
VM Region Info: 0x180000000 is not in any region. Bytes after previous region: 277577729 Bytes before following region: 384270336
   REGION TYPE         START - END   [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
   Stack          16f64c000-16f748000 [ 1008K] rw-/rwx SM=PRV thread 0
---> GAP OF 0x27730000 BYTES
   unused shlib __TEXT   196e78000-196eac000 [ 208K] r-x/r-x SM=COW ... this process
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [767]
```

Crashing code:
```
static mach_header *get_dyld_image_header() {
 unsigned depth = 1;
 vm_size_t size = 0;
 vm_address_t address = 0;
 kern_return_t err = KERN_SUCCESS;
 mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;

 while (true) {
  struct vm_region_submap_info_64 info;
  err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth,
                (vm_region_info_t)&info, &count);
  if (err != KERN_SUCCESS) return nullptr;

  if (size >= sizeof(mach_header) && info.protection & kProtectionRead) {
   mach_header *hdr = (mach_header *)address;
   if ((hdr->magic == MH_MAGIC || hdr->magic == MH_MAGIC_64) &&   // << CRASH: sanitizer_procmaps_mac.cpp:176
     hdr->filetype == MH_DYLINKER) {
    return hdr;
   }
  }
  address += size;
 }
}
```

Radar-Id: rdar://problem/86773501

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

Added: 
    

Modified: 
    compiler-rt/lib/lsan/lsan_common_mac.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_common_mac.cpp b/compiler-rt/lib/lsan/lsan_common_mac.cpp
index 6e8a6dfe16b45..a4204740c7fab 100644
--- a/compiler-rt/lib/lsan/lsan_common_mac.cpp
+++ b/compiler-rt/lib/lsan/lsan_common_mac.cpp
@@ -143,16 +143,16 @@ void ProcessGlobalRegions(Frontier *frontier) {
 }
 
 void ProcessPlatformSpecificAllocations(Frontier *frontier) {
-  unsigned depth = 1;
-  vm_size_t size = 0;
   vm_address_t address = 0;
   kern_return_t err = KERN_SUCCESS;
-  mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
 
   InternalMmapVectorNoCtor<RootRegion> const *root_regions = GetRootRegions();
 
   while (err == KERN_SUCCESS) {
+    vm_size_t size = 0;
+    unsigned depth = 1;
     struct vm_region_submap_info_64 info;
+    mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
     err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth,
                                (vm_region_info_t)&info, &count);
 

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
index 1f53e3e46d8fe..62b2e5e032166 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
@@ -143,16 +143,16 @@ void MemoryMappingLayout::LoadFromCache() {
 // early in the process, when dyld is one of the only images loaded,
 // so it will be hit after only a few iterations.
 static mach_header *get_dyld_image_header() {
-  unsigned depth = 1;
-  vm_size_t size = 0;
   vm_address_t address = 0;
-  kern_return_t err = KERN_SUCCESS;
-  mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
 
   while (true) {
+    vm_size_t size = 0;
+    unsigned depth = 1;
     struct vm_region_submap_info_64 info;
-    err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth,
-                               (vm_region_info_t)&info, &count);
+    mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
+    kern_return_t err =
+        vm_region_recurse_64(mach_task_self(), &address, &size, &depth,
+                             (vm_region_info_t)&info, &count);
     if (err != KERN_SUCCESS) return nullptr;
 
     if (size >= sizeof(mach_header) && info.protection & kProtectionRead) {


        


More information about the llvm-commits mailing list