Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[scudo] Add specific die functions for linux specific failures. #68650

Merged
merged 6 commits into from
Oct 13, 2023

Conversation

cferris1000
Copy link
Contributor

While running into failures on unmap calls, it becomes difficult to figure out what's wrong. Break the dieOnMapUnmapError into specific versions for map, unmap, and then one for mprotect.

Also, put these in a common linux space so that all linux derived code can reuse this code.

@llvmbot
Copy link
Collaborator

llvmbot commented Oct 10, 2023

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

Author: Christopher Ferris (cferris1000)

Changes

While running into failures on unmap calls, it becomes difficult to figure out what's wrong. Break the dieOnMapUnmapError into specific versions for map, unmap, and then one for mprotect.

Also, put these in a common linux space so that all linux derived code can reuse this code.


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

8 Files Affected:

  • (modified) compiler-rt/lib/scudo/standalone/CMakeLists.txt (+1)
  • (modified) compiler-rt/lib/scudo/standalone/common.cpp (-14)
  • (modified) compiler-rt/lib/scudo/standalone/common.h (-4)
  • (modified) compiler-rt/lib/scudo/standalone/linux.cpp (+4-5)
  • (added) compiler-rt/lib/scudo/standalone/linux_common.cpp (+65)
  • (added) compiler-rt/lib/scudo/standalone/linux_common.h (+34)
  • (modified) compiler-rt/lib/scudo/standalone/mem_map_linux.cpp (+6-5)
  • (modified) compiler-rt/lib/scudo/standalone/trusty.cpp (+3-4)
diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt
index c4d3ea1e4f05ba8..9738fb17d7f1241 100644
--- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt
+++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt
@@ -108,6 +108,7 @@ set(SCUDO_SOURCES
   flags.cpp
   fuchsia.cpp
   linux.cpp
+  linux_common.cpp
   mem_map.cpp
   mem_map_fuchsia.cpp
   mem_map_linux.cpp
diff --git a/compiler-rt/lib/scudo/standalone/common.cpp b/compiler-rt/lib/scudo/standalone/common.cpp
index 666f95400c7e7aa..06e930638f6f971 100644
--- a/compiler-rt/lib/scudo/standalone/common.cpp
+++ b/compiler-rt/lib/scudo/standalone/common.cpp
@@ -21,18 +21,4 @@ uptr getPageSizeSlow() {
   return PageSizeCached;
 }
 
-// Fatal internal map() or unmap() error (potentially OOM related).
-void NORETURN dieOnMapUnmapError(uptr SizeIfOOM) {
-  char Error[128] = "Scudo ERROR: internal map or unmap failure\n";
-  if (SizeIfOOM) {
-    formatString(
-        Error, sizeof(Error),
-        "Scudo ERROR: internal map failure (NO MEMORY) requesting %zuKB\n",
-        SizeIfOOM >> 10);
-  }
-  outputRaw(Error);
-  setAbortMessage(Error);
-  die();
-}
-
 } // namespace scudo
diff --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h
index d0f429cfcb7a08e..3581c946d1608fc 100644
--- a/compiler-rt/lib/scudo/standalone/common.h
+++ b/compiler-rt/lib/scudo/standalone/common.h
@@ -175,10 +175,6 @@ void setMemoryPermission(uptr Addr, uptr Size, uptr Flags,
 void releasePagesToOS(uptr BaseAddress, uptr Offset, uptr Size,
                       MapPlatformData *Data = nullptr);
 
-// Internal map & unmap fatal error. This must not call map(). SizeIfOOM shall
-// hold the requested size on an out-of-memory error, 0 otherwise.
-void NORETURN dieOnMapUnmapError(uptr SizeIfOOM = 0);
-
 // Logging related functions.
 
 void setAbortMessage(const char *Message);
diff --git a/compiler-rt/lib/scudo/standalone/linux.cpp b/compiler-rt/lib/scudo/standalone/linux.cpp
index c31c3d2483a97ad..3e3b2147b3c77c1 100644
--- a/compiler-rt/lib/scudo/standalone/linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/linux.cpp
@@ -13,6 +13,7 @@
 #include "common.h"
 #include "internal_defs.h"
 #include "linux.h"
+#include "linux_common.h"
 #include "mutex.h"
 #include "string_utils.h"
 
@@ -41,8 +42,6 @@ namespace scudo {
 
 uptr getPageSize() { return static_cast<uptr>(sysconf(_SC_PAGESIZE)); }
 
-void NORETURN die() { abort(); }
-
 // TODO: Will be deprecated. Use the interfaces in MemMapLinux instead.
 void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
           UNUSED MapPlatformData *Data) {
@@ -66,7 +65,7 @@ void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
   void *P = mmap(Addr, Size, MmapProt, MmapFlags, -1, 0);
   if (P == MAP_FAILED) {
     if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
-      dieOnMapUnmapError(errno == ENOMEM ? Size : 0);
+      dieOnMapError(errno == ENOMEM ? Size : 0);
     return nullptr;
   }
 #if SCUDO_ANDROID
@@ -80,7 +79,7 @@ void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
 void unmap(void *Addr, uptr Size, UNUSED uptr Flags,
            UNUSED MapPlatformData *Data) {
   if (munmap(Addr, Size) != 0)
-    dieOnMapUnmapError();
+    dieOnUnmapError(reinterpret_cast<uptr>(Addr), Size);
 }
 
 // TODO: Will be deprecated. Use the interfaces in MemMapLinux instead.
@@ -88,7 +87,7 @@ void setMemoryPermission(uptr Addr, uptr Size, uptr Flags,
                          UNUSED MapPlatformData *Data) {
   int Prot = (Flags & MAP_NOACCESS) ? PROT_NONE : (PROT_READ | PROT_WRITE);
   if (mprotect(reinterpret_cast<void *>(Addr), Size, Prot) != 0)
-    dieOnMapUnmapError();
+    dieOnProtectError(Addr, Size, Prot);
 }
 
 // TODO: Will be deprecated. Use the interfaces in MemMapLinux instead.
diff --git a/compiler-rt/lib/scudo/standalone/linux_common.cpp b/compiler-rt/lib/scudo/standalone/linux_common.cpp
new file mode 100644
index 000000000000000..d0e39fb0ced87e3
--- /dev/null
+++ b/compiler-rt/lib/scudo/standalone/linux_common.cpp
@@ -0,0 +1,65 @@
+//===-- linux_common.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "platform.h"
+
+#if SCUDO_LINUX
+
+#include "common.h"
+#include "internal_defs.h"
+#include "linux_common.h"
+#include "string_utils.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace scudo {
+
+void NORETURN die() { abort(); }
+
+// Fatal internal map() error (potentially OOM related).
+void NORETURN dieOnMapError(uptr SizeIfOOM) {
+  char Error[128] = "Scudo ERROR: internal map failure\n";
+  if (SizeIfOOM) {
+    formatString(
+        Error, sizeof(Error),
+        "Scudo ERROR: internal map failure (NO MEMORY) requesting %zuKB\n",
+        SizeIfOOM >> 10);
+  }
+  outputRaw(Error);
+  setAbortMessage(Error);
+  die();
+}
+
+void NORETURN dieOnUnmapError(uptr Addr, uptr Size) {
+  char Error[128];
+  formatString(Error, sizeof(Error),
+               "Scudo ERROR: internal unmap failure (error desc=%s) Addr 0x%zx "
+               "Size %zu\n",
+               strerror(errno), Addr, Size);
+  outputRaw(Error);
+  setAbortMessage(Error);
+  die();
+}
+
+void NORETURN dieOnProtectError(uptr Addr, uptr Size, int Prot) {
+  char Error[128];
+  formatString(
+      Error, sizeof(Error),
+      "Scudo ERROR: internal protect failure (error desc=%s) Addr 0x%zx "
+      "Size %zu Prot %x\n",
+      strerror(errno), Addr, Size, Prot);
+  outputRaw(Error);
+  setAbortMessage(Error);
+  die();
+}
+
+} // namespace scudo
+
+#endif // SCUDO_LINUX
diff --git a/compiler-rt/lib/scudo/standalone/linux_common.h b/compiler-rt/lib/scudo/standalone/linux_common.h
new file mode 100644
index 000000000000000..6a5c528a040168b
--- /dev/null
+++ b/compiler-rt/lib/scudo/standalone/linux_common.h
@@ -0,0 +1,34 @@
+//===-- linux_common.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCUDO_LINUX_COMMON_H_
+#define SCUDO_LINUX_COMMON_H_
+
+#include "platform.h"
+
+#if SCUDO_LINUX
+
+#include "internal_defs.h"
+
+namespace scudo {
+
+// Internal map fatal error. This must not call map(). SizeIfOOM shall
+// hold the requested size on an out-of-memory error, 0 otherwise.
+void NORETURN dieOnMapError(uptr SizeIfOOM = 0);
+
+// Internal unmap fatal error. This must not call map().
+void NORETURN dieOnUnmapError(uptr Addr, uptr Size);
+
+// Internal protect fatal error. This must not call map().
+void NORETURN dieOnProtectError(uptr Addr, uptr Size, int Prot);
+
+} // namespace scudo
+
+#endif // SCUDO_LINUX
+
+#endif // SCUDO_LINUX_COMMON_H_
diff --git a/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp b/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
index f377d105894db7d..8e55599398b956b 100644
--- a/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/mem_map_linux.cpp
@@ -15,6 +15,7 @@
 #include "common.h"
 #include "internal_defs.h"
 #include "linux.h"
+#include "linux_common.h"
 #include "mutex.h"
 #include "string_utils.h"
 
@@ -64,7 +65,7 @@ static void *mmapWrapper(uptr Addr, uptr Size, const char *Name, uptr Flags) {
       mmap(reinterpret_cast<void *>(Addr), Size, MmapProt, MmapFlags, -1, 0);
   if (P == MAP_FAILED) {
     if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
-      dieOnMapUnmapError(errno == ENOMEM ? Size : 0);
+      dieOnMapError(errno == ENOMEM ? Size : 0);
     return nullptr;
   }
 #if SCUDO_ANDROID
@@ -101,21 +102,21 @@ void MemMapLinux::unmapImpl(uptr Addr, uptr Size) {
   }
 
   if (munmap(reinterpret_cast<void *>(Addr), Size) != 0)
-    dieOnMapUnmapError();
+    dieOnUnmapError(Addr, 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)
-    dieOnMapUnmapError();
+    dieOnMapError();
   return true;
 }
 
 void MemMapLinux::setMemoryPermissionImpl(uptr Addr, uptr Size, uptr Flags) {
   int Prot = (Flags & MAP_NOACCESS) ? PROT_NONE : (PROT_READ | PROT_WRITE);
   if (mprotect(reinterpret_cast<void *>(Addr), Size, Prot) != 0)
-    dieOnMapUnmapError();
+    dieOnProtectError(Addr, Size, Prot);
 }
 
 void MemMapLinux::releaseAndZeroPagesToOSImpl(uptr From, uptr Size) {
@@ -139,7 +140,7 @@ bool ReservedMemoryLinux::createImpl(uptr Addr, uptr Size, const char *Name,
 
 void ReservedMemoryLinux::releaseImpl() {
   if (munmap(reinterpret_cast<void *>(getBase()), getCapacity()) != 0)
-    dieOnMapUnmapError();
+    dieOnUnmapError(getBase(), getCapacity());
 }
 
 ReservedMemoryLinux::MemMapT ReservedMemoryLinux::dispatchImpl(uptr Addr,
diff --git a/compiler-rt/lib/scudo/standalone/trusty.cpp b/compiler-rt/lib/scudo/standalone/trusty.cpp
index 5f72b1cb3e54b05..daa72ba0c4bf3b1 100644
--- a/compiler-rt/lib/scudo/standalone/trusty.cpp
+++ b/compiler-rt/lib/scudo/standalone/trusty.cpp
@@ -11,6 +11,7 @@
 #if SCUDO_TRUSTY
 
 #include "common.h"
+#include "linux_common.h"
 #include "mutex.h"
 #include "trusty.h"
 
@@ -28,8 +29,6 @@ namespace scudo {
 
 uptr getPageSize() { return getauxval(AT_PAGESZ); }
 
-void NORETURN die() { abort(); }
-
 void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
           UNUSED MapPlatformData *Data) {
   uint32_t MmapFlags =
@@ -51,7 +50,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
   if (IS_ERR(P)) {
     errno = lk_err_to_errno(PTR_ERR(P));
     if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
-      dieOnMapUnmapError(Size);
+      dieOnMapError(Size);
     return nullptr;
   }
 
@@ -61,7 +60,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
 void unmap(UNUSED void *Addr, UNUSED uptr Size, UNUSED uptr Flags,
            UNUSED MapPlatformData *Data) {
   if (_trusty_munmap(Addr, Size) != 0)
-    dieOnMapUnmapError();
+    dieOnUnmapError(Addr, Size);
 }
 
 void setMemoryPermission(UNUSED uptr Addr, UNUSED uptr Size, UNUSED uptr Flags,

Copy link
Contributor

@ChiaHungDuan ChiaHungDuan left a comment

Choose a reason for hiding this comment

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

Only very few coding style suggestions

compiler-rt/lib/scudo/standalone/linux_common.cpp Outdated Show resolved Hide resolved
compiler-rt/lib/scudo/standalone/CMakeLists.txt Outdated Show resolved Hide resolved
compiler-rt/lib/scudo/standalone/linux_common.h Outdated Show resolved Hide resolved
Copy link
Contributor

@ChiaHungDuan ChiaHungDuan left a comment

Choose a reason for hiding this comment

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

Looks nice!

@github-actions
Copy link

github-actions bot commented Oct 11, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

While running into failures on unmap calls, it becomes difficult
to figure out what's wrong. Break the dieOnMapUnmapError into
specific Report versions for map, unmap, and then one for mprotect.

Also, put these in a common report linux file so that all linux derived
code can reuse this code.

Finally, add a ReportRawError that is used by all of the code so that
it's all in the same space.
Move the dieOnXXX routines to reportXXX. Mv linux_common to report_linux.

Add a new reportRawError function that doesn't use ScopedString.
Move the die definitions in trusty.cpp and linux.cpp to their original
location to avoid unnecessary churn in the files.
@cferris1000
Copy link
Contributor Author

Fixed the comment on the first message to actually reflect what was done.

@ChiaHungDuan
Copy link
Contributor

Still LGTM

Copy link
Contributor

@fabio-d fabio-d left a comment

Choose a reason for hiding this comment

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

Thanks!

@cferris1000 cferris1000 merged commit 99d92d1 into llvm:main Oct 13, 2023
3 checks passed
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.

None yet

4 participants