Skip to content

[scudo] Return nullptr if a remap fails on linux.#200537

Merged
cferris1000 merged 1 commit into
llvm:mainfrom
cferris1000:remap_allow_fail
Jun 2, 2026
Merged

[scudo] Return nullptr if a remap fails on linux.#200537
cferris1000 merged 1 commit into
llvm:mainfrom
cferris1000:remap_allow_fail

Conversation

@cferris1000
Copy link
Copy Markdown
Contributor

Add a check if a fixed address mmap doesn't return the expected address.

Allow a remap call to fail if the mmap fails and returns a nullptr to the caller.

Fix a place where if remap fails in the secondary, it didn't do anything. Now it will unmap the original entry on failure.

Add a check if a fixed address mmap doesn't return the expected
address.

Allow a remap call to fail if the mmap fails and returns a nullptr
to the caller.

Fix a place where if remap fails in the secondary, it didn't
do anything. Now it will unmap the original entry on failure.
@llvmorg-github-actions
Copy link
Copy Markdown

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

Author: Christopher Ferris (cferris1000)

Changes

Add a check if a fixed address mmap doesn't return the expected address.

Allow a remap call to fail if the mmap fails and returns a nullptr to the caller.

Fix a place where if remap fails in the secondary, it didn't do anything. Now it will unmap the original entry on failure.


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

5 Files Affected:

  • (modified) compiler-rt/lib/scudo/standalone/mem_map_linux.cpp (+5-3)
  • (modified) compiler-rt/lib/scudo/standalone/report_linux.cpp (+8)
  • (modified) compiler-rt/lib/scudo/standalone/report_linux.h (+4)
  • (modified) compiler-rt/lib/scudo/standalone/secondary.h (+7-2)
  • (modified) compiler-rt/lib/scudo/standalone/tests/report_test.cpp (+3)
diff --git a/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp b/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
index b34bef593acdb..2a5e8b50743bd 100644
--- a/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
@@ -68,6 +68,10 @@ static void *mmapWrapper(uptr Addr, uptr Size, const char *Name, uptr Flags) {
       reportMapError(errno == ENOMEM ? Size : 0);
     return nullptr;
   }
+
+  if (Addr && reinterpret_cast<uptr>(P) != Addr)
+    reportMapFixedError(reinterpret_cast<uptr>(P), Addr);
+
 #if SCUDO_ANDROID
   if (Name)
     prctl(ANDROID_PR_SET_VMA, ANDROID_PR_SET_VMA_ANON_NAME, P, Size, Name);
@@ -108,9 +112,7 @@ void MemMapLinux::unmapImpl(uptr Addr, uptr Size) {
 bool MemMapLinux::remapImpl(uptr Addr, uptr Size, const char *Name,
                             uptr Flags) {
   void *P = mmapWrapper(Addr, Size, Name, Flags);
-  if (reinterpret_cast<uptr>(P) != Addr)
-    reportMapError();
-  return true;
+  return reinterpret_cast<uptr>(P) == Addr;
 }
 
 void MemMapLinux::setMemoryPermissionImpl(uptr Addr, uptr Size, uptr Flags) {
diff --git a/compiler-rt/lib/scudo/standalone/report_linux.cpp b/compiler-rt/lib/scudo/standalone/report_linux.cpp
index 432f6a0169646..b790b994529ac 100644
--- a/compiler-rt/lib/scudo/standalone/report_linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/report_linux.cpp
@@ -33,6 +33,14 @@ void NORETURN reportMapError(uptr SizeIfOOM) {
   reportRawError(Error.data());
 }
 
+void NORETURN reportMapFixedError(uptr ExpectedAddr, uptr RequestedAddr) {
+  ScopedString Error;
+  Error.append("Scudo ERROR: internal map failure using fixed address "
+               "(expected: 0x%zx requested: 0x%zx)\n",
+               ExpectedAddr, RequestedAddr);
+  reportRawError(Error.data());
+}
+
 void NORETURN reportUnmapError(uptr Addr, uptr Size) {
   ScopedString Error;
   Error.append("Scudo ERROR: internal unmap failure (error desc=%s) Addr 0x%zx "
diff --git a/compiler-rt/lib/scudo/standalone/report_linux.h b/compiler-rt/lib/scudo/standalone/report_linux.h
index aa0bb247e6723..ffbd50f4e1318 100644
--- a/compiler-rt/lib/scudo/standalone/report_linux.h
+++ b/compiler-rt/lib/scudo/standalone/report_linux.h
@@ -21,6 +21,10 @@ namespace scudo {
 // hold the requested size on an out-of-memory error, 0 otherwise.
 void NORETURN reportMapError(uptr SizeIfOOM = 0);
 
+// Report a fatal error when a map call using a fixed address doesn't
+// return the requested address.
+void NORETURN reportMapFixedError(uptr ExpectedAddr, uptr RequestedAddr);
+
 // Report a fatal error when an unmap call fails.
 void NORETURN reportUnmapError(uptr Addr, uptr Size);
 
diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h
index cce8f47eda54c..a689ea9b1e5aa 100644
--- a/compiler-rt/lib/scudo/standalone/secondary.h
+++ b/compiler-rt/lib/scudo/standalone/secondary.h
@@ -306,8 +306,13 @@ class MapAllocatorCache {
         // Fuchsia does not support replacing mappings by creating a new mapping
         // on top so we just do the two syscalls there.
         Entry.Time = 0;
-        mapSecondary<Config>(Options, Entry.CommitBase, Entry.CommitSize,
-                             Entry.CommitBase, MAP_NOACCESS, Entry.MemMap);
+        if (!mapSecondary<Config>(Options, Entry.CommitBase, Entry.CommitSize,
+                                  Entry.CommitBase, MAP_NOACCESS,
+                                  Entry.MemMap)) {
+          // A mmap failed, unmap and return.
+          unmapCallBack(Entry.MemMap);
+          return;
+        }
       } else {
         Entry.MemMap.setMemoryPermission(Entry.CommitBase, Entry.CommitSize,
                                          MAP_NOACCESS);
diff --git a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp
index e69291cc004b8..e69f5dcc24fa7 100644
--- a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp
@@ -105,6 +105,9 @@ TEST(ScudoReportDeathTest, Linux) {
   EXPECT_DEATH(scudo::reportMapError(1024U),
                "Scudo ERROR:.*internal map failure \\(error desc=.*\\) "
                "requesting 1KB");
+  EXPECT_DEATH(scudo::reportMapFixedError(0x1000U, 0x2000U),
+               "Scudo ERROR:.*internal map failure using fixed address "
+               "\\(expected: 0x1000 requested: 0x2000\\)");
   errno = ENOMEM;
   EXPECT_DEATH(scudo::reportUnmapError(0x1000U, 100U),
                "Scudo ERROR:.*internal unmap failure \\(error desc=.*\\) Addr "

@cferris1000 cferris1000 merged commit adcd285 into llvm:main Jun 2, 2026
14 checks passed
@cferris1000 cferris1000 deleted the remap_allow_fail branch June 2, 2026 04:49
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Jun 5, 2026
Add a check if a fixed address mmap doesn't return the expected address.

Allow a remap call to fail if the mmap fails and returns a nullptr to
the caller.

Fix a place where if remap fails in the secondary, it didn't do
anything. Now it will unmap the original entry on failure.
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.

2 participants