[scudo] Add specific die functions for linux specific failures. (#68650) am: b2c81dae29
Original change: https://android-review.googlesource.com/c/platform/external/scudo/+/2786448
Change-Id: I1a68eae69af63b3abac231fcb973115dc58a1d30
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/standalone/common.cpp b/standalone/common.cpp
index 666f954..06e9306 100644
--- a/standalone/common.cpp
+++ b/standalone/common.cpp
@@ -21,18 +21,4 @@
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/standalone/common.h b/standalone/common.h
index d0f429c..3581c94 100644
--- a/standalone/common.h
+++ b/standalone/common.h
@@ -175,10 +175,6 @@
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/standalone/linux.cpp b/standalone/linux.cpp
index c31c3d2..2746951 100644
--- a/standalone/linux.cpp
+++ b/standalone/linux.cpp
@@ -14,6 +14,7 @@
#include "internal_defs.h"
#include "linux.h"
#include "mutex.h"
+#include "report_linux.h"
#include "string_utils.h"
#include <errno.h>
@@ -66,7 +67,7 @@
void *P = mmap(Addr, Size, MmapProt, MmapFlags, -1, 0);
if (P == MAP_FAILED) {
if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
- dieOnMapUnmapError(errno == ENOMEM ? Size : 0);
+ reportMapError(errno == ENOMEM ? Size : 0);
return nullptr;
}
#if SCUDO_ANDROID
@@ -80,7 +81,7 @@
void unmap(void *Addr, uptr Size, UNUSED uptr Flags,
UNUSED MapPlatformData *Data) {
if (munmap(Addr, Size) != 0)
- dieOnMapUnmapError();
+ reportUnmapError(reinterpret_cast<uptr>(Addr), Size);
}
// TODO: Will be deprecated. Use the interfaces in MemMapLinux instead.
@@ -88,7 +89,7 @@
UNUSED MapPlatformData *Data) {
int Prot = (Flags & MAP_NOACCESS) ? PROT_NONE : (PROT_READ | PROT_WRITE);
if (mprotect(reinterpret_cast<void *>(Addr), Size, Prot) != 0)
- dieOnMapUnmapError();
+ reportProtectError(Addr, Size, Prot);
}
// TODO: Will be deprecated. Use the interfaces in MemMapLinux instead.
diff --git a/standalone/mem_map_linux.cpp b/standalone/mem_map_linux.cpp
index f377d10..783c4f0 100644
--- a/standalone/mem_map_linux.cpp
+++ b/standalone/mem_map_linux.cpp
@@ -16,6 +16,7 @@
#include "internal_defs.h"
#include "linux.h"
#include "mutex.h"
+#include "report_linux.h"
#include "string_utils.h"
#include <errno.h>
@@ -64,7 +65,7 @@
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);
+ reportMapError(errno == ENOMEM ? Size : 0);
return nullptr;
}
#if SCUDO_ANDROID
@@ -101,21 +102,21 @@
}
if (munmap(reinterpret_cast<void *>(Addr), Size) != 0)
- dieOnMapUnmapError();
+ reportUnmapError(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();
+ reportMapError();
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();
+ reportProtectError(Addr, Size, Prot);
}
void MemMapLinux::releaseAndZeroPagesToOSImpl(uptr From, uptr Size) {
@@ -139,7 +140,7 @@
void ReservedMemoryLinux::releaseImpl() {
if (munmap(reinterpret_cast<void *>(getBase()), getCapacity()) != 0)
- dieOnMapUnmapError();
+ reportUnmapError(getBase(), getCapacity());
}
ReservedMemoryLinux::MemMapT ReservedMemoryLinux::dispatchImpl(uptr Addr,
diff --git a/standalone/report.cpp b/standalone/report.cpp
index c033949..9cef0ad 100644
--- a/standalone/report.cpp
+++ b/standalone/report.cpp
@@ -24,11 +24,7 @@
Message.vappend(Format, Args);
va_end(Args);
}
- NORETURN ~ScopedErrorReport() {
- outputRaw(Message.data());
- setAbortMessage(Message.data());
- die();
- }
+ NORETURN ~ScopedErrorReport() { reportRawError(Message.data()); }
private:
ScopedString Message;
@@ -55,6 +51,13 @@
Report.append("%s\n", Message);
}
+// Generic fatal error message without ScopedString.
+void NORETURN reportRawError(const char *Message) {
+ outputRaw(Message);
+ setAbortMessage(Message);
+ die();
+}
+
void NORETURN reportInvalidFlag(const char *FlagType, const char *Value) {
ScopedErrorReport Report;
Report.append("invalid value for %s option: '%s'\n", FlagType, Value);
diff --git a/standalone/report.h b/standalone/report.h
index d8c2dea..a510fda 100644
--- a/standalone/report.h
+++ b/standalone/report.h
@@ -15,9 +15,12 @@
// Reports are *fatal* unless stated otherwise.
-// Generic error.
+// Generic error, adds newline to end of message.
void NORETURN reportError(const char *Message);
+// Generic error, but the message is not modified.
+void NORETURN reportRawError(const char *Message);
+
// Flags related errors.
void NORETURN reportInvalidFlag(const char *FlagType, const char *Value);
diff --git a/standalone/report_linux.cpp b/standalone/report_linux.cpp
new file mode 100644
index 0000000..6a98303
--- /dev/null
+++ b/standalone/report_linux.cpp
@@ -0,0 +1,58 @@
+//===-- report_linux.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 || SCUDO_TRUSTY
+
+#include "common.h"
+#include "internal_defs.h"
+#include "report.h"
+#include "report_linux.h"
+#include "string_utils.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace scudo {
+
+// Fatal internal map() error (potentially OOM related).
+void NORETURN reportMapError(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);
+ }
+ reportRawError(Error);
+}
+
+void NORETURN reportUnmapError(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);
+ reportRawError(Error);
+}
+
+void NORETURN reportProtectError(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);
+ reportRawError(Error);
+}
+
+} // namespace scudo
+
+#endif // SCUDO_LINUX || SCUDO_TRUSTY
diff --git a/standalone/report_linux.h b/standalone/report_linux.h
new file mode 100644
index 0000000..aa0bb24
--- /dev/null
+++ b/standalone/report_linux.h
@@ -0,0 +1,34 @@
+//===-- report_linux.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_REPORT_LINUX_H_
+#define SCUDO_REPORT_LINUX_H_
+
+#include "platform.h"
+
+#if SCUDO_LINUX || SCUDO_TRUSTY
+
+#include "internal_defs.h"
+
+namespace scudo {
+
+// Report a fatal error when a map call fails. SizeIfOOM shall
+// hold the requested size on an out-of-memory error, 0 otherwise.
+void NORETURN reportMapError(uptr SizeIfOOM = 0);
+
+// Report a fatal error when an unmap call fails.
+void NORETURN reportUnmapError(uptr Addr, uptr Size);
+
+// Report a fatal error when a mprotect call fails.
+void NORETURN reportProtectError(uptr Addr, uptr Size, int Prot);
+
+} // namespace scudo
+
+#endif // SCUDO_LINUX || SCUDO_TRUSTY
+
+#endif // SCUDO_REPORT_LINUX_H_
diff --git a/standalone/trusty.cpp b/standalone/trusty.cpp
index 5f72b1c..26bc8e5 100644
--- a/standalone/trusty.cpp
+++ b/standalone/trusty.cpp
@@ -12,6 +12,7 @@
#include "common.h"
#include "mutex.h"
+#include "report_linux.h"
#include "trusty.h"
#include <errno.h> // for errno
@@ -51,7 +52,7 @@
if (IS_ERR(P)) {
errno = lk_err_to_errno(PTR_ERR(P));
if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
- dieOnMapUnmapError(Size);
+ reportMapError(Size);
return nullptr;
}
@@ -61,7 +62,7 @@
void unmap(UNUSED void *Addr, UNUSED uptr Size, UNUSED uptr Flags,
UNUSED MapPlatformData *Data) {
if (_trusty_munmap(Addr, Size) != 0)
- dieOnMapUnmapError();
+ reportUnmapError(Addr, Size);
}
void setMemoryPermission(UNUSED uptr Addr, UNUSED uptr Size, UNUSED uptr Flags,