Skip to content

Conversation

ndrewh
Copy link
Contributor

@ndrewh ndrewh commented Sep 15, 2025

An existing log message is triggered in InitializePlatformEarly if the address space max is not as sufficient for TSAN.

Some Apple platforms expand the address space limit, but reserve much of the space TSAN needs. Therefore, we now check that the kernel has not mapped over the address space that we intend to use.

IsAddressInMappedRegion is added to sanitizer_common. This introduces a new dependency on mach_vm_region_recurse during TSAN startup, so this intentionally fails softly (to avoid breaking current users who may be in a sandbox that doesn't allow this).

rdar://135265279

An existing log message is triggered in InitializePlatformEarly if
the address space max is not as sufficient for TSAN.

Some platforms expand the address space limit, but reserve much
of the space TSAN needs. Therefore, we now check that the kernel
has not mapped over the address space that we intend to use.

IsAddressInMappedRegion is added to sanitizer_common. This introduces
a new dependency on mach_vm_region_recurse during TSAN startup, so this
intentionally fails softly (to avoid breaking current users who
may be in a sandbox that doesn't allow this).

rdar://135265279
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Sep 15, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Andrew Haberlandt (ndrewh)

Changes

An existing log message is triggered in InitializePlatformEarly if the address space max is not as sufficient for TSAN.

Some Apple platforms expand the address space limit, but reserve much of the space TSAN needs. Therefore, we now check that the kernel has not mapped over the address space that we intend to use.

IsAddressInMappedRegion is added to sanitizer_common. This introduces a new dependency on mach_vm_region_recurse during TSAN startup, so this intentionally fails softly (to avoid breaking current users who may be in a sandbox that doesn't allow this).

rdar://135265279


Full diff: https://github.com/llvm/llvm-project/pull/158665.diff

3 Files Affected:

  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp (+23)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_mac.h (+2)
  • (modified) compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp (+13-3)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index d4811ff4ed217..bf861063ca1f5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -1298,6 +1298,29 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
   return 0;
 }
 
+// Returns true if the address is definitely mapped, and false if it is not
+// mapped or could not be determined.
+bool IsAddressInMappedRegion(uptr addr) {
+  mach_vm_size_t vmsize = 0;
+  natural_t depth = 0;
+  vm_region_submap_short_info_data_64_t vminfo;
+  mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
+  mach_vm_address_t address = addr;
+
+  kern_return_t kr =
+      mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
+                             (vm_region_info_t)&vminfo, &count);
+
+  if (kr == KERN_DENIED) {
+    Report(
+        "WARN: mach_vm_region_recurse returned KERN_DENIED when checking "
+        "whether an address is mapped.\n");
+    Report("HINT: Is mach_vm_region_recurse allowed by sandbox?\n");
+  }
+
+  return (kr == KERN_SUCCESS && addr >= address && addr < address + vmsize);
+}
+
 // FIXME implement on this platform.
 void GetMemoryProfile(fill_profile_f cb, uptr *stats) {}
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
index b0e4ac7f40745..789dd8e4d8e9c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
@@ -76,6 +76,8 @@ struct ThreadEventCallbacks {
 
 void InstallPthreadIntrospectionHook(const ThreadEventCallbacks &callbacks);
 
+bool IsAddressInMappedRegion(uptr addr);
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_APPLE
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
index eb344df168ab9..84dfe999045f9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
@@ -226,9 +226,19 @@ static void ThreadTerminateCallback(uptr thread) {
 void InitializePlatformEarly() {
 #  if !SANITIZER_GO && SANITIZER_IOS
   uptr max_vm = GetMaxUserVirtualAddress() + 1;
-  if (max_vm != HiAppMemEnd()) {
-    Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n",
-           (void *)max_vm, (void *)HiAppMemEnd());
+  if (max_vm < HiAppMemEnd()) {
+    Printf(
+        "ThreadSanitizer: Unsupported virtual memory layout:\n\tVM address "
+        "limit = %p\n\tExpected %p.\n",
+        (void*)max_vm, (void*)HiAppMemEnd());
+    Die();
+  }
+  // In some configurations, the max_vm is expanded, but much of this space is
+  // already mapped. TSAN will not work in this configuration.
+  else if (IsAddressInMappedRegion(HiAppMemEnd() - 1)) {
+    Printf(
+        "ThreadSanitizer: Unsupported virtual memory layout: Address %p is "
+        "already mapped.\n");
     Die();
   }
 #endif

Copy link
Contributor

@DanBlackwell DanBlackwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know what your thoughts are with respect to printf vs report for the fatal paths. Happy to merge this for you afterwards; this is a useful contribution!

@ndrewh ndrewh requested a review from DanBlackwell September 17, 2025 00:10
@ndrewh ndrewh changed the title [sanitizer_common][tsan] Improve message for unsupported vm config on Apple platforms [sanitizer_common][tsan][Darwin] Improve message for unsupported vm config on Apple platforms Sep 17, 2025
@DanBlackwell
Copy link
Contributor

@ndrewh let me know if you want this merging and I'll hit the button for you.

@ndrewh
Copy link
Contributor Author

ndrewh commented Sep 17, 2025

good with me to merge @DanBlackwell

@DanBlackwell DanBlackwell merged commit 51a840e into llvm:main Sep 17, 2025
9 checks passed
Copy link

@ndrewh Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

ndrewh added a commit to ndrewh/llvm-project that referenced this pull request Sep 22, 2025
wrotki pushed a commit that referenced this pull request Sep 22, 2025
@ndrewh ndrewh deleted the tsan-missing-bootarg-diagnostic branch October 11, 2025 00:36
ndrewh added a commit to swiftlang/llvm-project that referenced this pull request Oct 11, 2025
…onfig on Apple platforms (llvm#158665)

An existing log message is triggered in InitializePlatformEarly if the
address space max is not as sufficient for TSAN.

Some Apple platforms expand the address space limit, but reserve much of
the space TSAN needs. Therefore, we now check that the kernel has not
mapped over the address space that we intend to use.

IsAddressInMappedRegion is added to sanitizer_common. This introduces a
new dependency on mach_vm_region_recurse during TSAN startup, so this
intentionally fails softly (to avoid breaking current users who may be
in a sandbox that doesn't allow this).

rdar://135265279
(cherry picked from commit 51a840e)
ndrewh added a commit to swiftlang/llvm-project that referenced this pull request Oct 11, 2025
…sg (llvm#160171)

This fixes a typo introduced in llvm#158665.

(cherry picked from commit e99c43c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants