summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2023-01-11 13:17:17 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2023-01-11 13:17:17 +0000
commit68d1631e982c05e2bf0dd7dcbc1de8d87f5da3d4 (patch)
tree05dbf471befa6a5ac1c63c53c35e27a72a1100ff /vespalib
parentde82bfc3fe492c406a69799f11530fe3b9b97d57 (diff)
Reduce number of `#ifdef`s
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/util/memory_trap.cpp132
1 files changed, 65 insertions, 67 deletions
diff --git a/vespalib/src/vespa/vespalib/util/memory_trap.cpp b/vespalib/src/vespa/vespalib/util/memory_trap.cpp
index 113af0de35a..f17a0221246 100644
--- a/vespalib/src/vespa/vespalib/util/memory_trap.cpp
+++ b/vespalib/src/vespa/vespalib/util/memory_trap.cpp
@@ -1,9 +1,5 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#ifdef __linux__
-# define VESPA_HAS_MPROTECT
-#endif
-
#include "memory_trap.h"
#include <string_view>
#include <cassert>
@@ -12,7 +8,8 @@
#include <cstdlib>
#include <cstring>
#include <malloc.h>
-#ifdef VESPA_HAS_MPROTECT
+#ifdef __linux__
+# define VESPA_HAS_MPROTECT
# include <unistd.h>
# include <sys/mman.h>
#endif
@@ -26,36 +23,6 @@ namespace vespalib {
namespace {
-#ifdef VESPA_HAS_MPROTECT
-
-bool has_4k_pages() noexcept {
- return (sysconf(_SC_PAGESIZE) == 4096);
-}
-
-constexpr bool is_4k_aligned(size_t v) noexcept {
- return (v % 4096) == 0;
-}
-
-constexpr size_t align_up_4k(size_t v) noexcept {
- return (v + 4095) & ~4095ULL;
-}
-
-constexpr size_t align_down_4k(size_t v) noexcept {
- return v & ~4095ULL;
-}
-
-bool env_var_is_yes(const char* env_var) noexcept {
- const char* ev = getenv(env_var);
- return ((ev != nullptr) && ("yes"sv == ev));
-}
-
-bool mprotect_trapping_is_enabled() noexcept {
- static const bool enabled = (has_4k_pages() && env_var_is_yes("VESPA_USE_MPROTECT_TRAP"));
- return enabled;
-}
-
-#endif
-
// Have some symbols that provide immediate context in a crash backtrace
[[noreturn]] void abort_due_to_guard_bits_tampered_with() __attribute__((noinline));
[[noreturn]] void abort_due_to_guard_bits_tampered_with() {
@@ -85,8 +52,62 @@ MemoryRangeTrapper::~MemoryRangeTrapper() {
check_and_release();
}
-void MemoryRangeTrapper::rw_protect_buffer_if_possible() {
+void MemoryRangeTrapper::check_and_release() noexcept {
+ unprotect_buffer_to_read_only(); // Make sure sanity check can't race with writes
+ verify_buffer_is_all_zeros();
+ unprotect_buffer_to_read_and_write();
+ _trap_len = _buf_len = 0;
+}
+
+void MemoryRangeTrapper::verify_buffer_is_all_zeros() {
+ for (size_t i = 0; i < _buf_len; ++i) {
+ if (_trap_buf[i] != 0) {
+ const bool in_protected_area = ((i >= _trap_offset) && (i < _trap_offset + _trap_len));
+ LOG(error, "Memory corruption detected! Offset %zu into buffer %p: 0x%.2x != 0x00%s",
+ i, _trap_buf, static_cast<unsigned int>(_trap_buf[i]),
+ in_protected_area ? ". CORRUPTION IN R/W PROTECTED MEMORY!" : "");
+ if (in_protected_area) {
+ abort_due_to_PROTECTED_guard_bits_tampered_with();
+ } else {
+ abort_due_to_guard_bits_tampered_with();
+ }
+ }
+ }
+}
+
#ifdef VESPA_HAS_MPROTECT
+
+namespace {
+
+bool has_4k_pages() noexcept {
+ return (sysconf(_SC_PAGESIZE) == 4096);
+}
+
+constexpr bool is_4k_aligned(size_t v) noexcept {
+ return (v % 4096) == 0;
+}
+
+constexpr size_t align_up_4k(size_t v) noexcept {
+ return (v + 4095) & ~4095ULL;
+}
+
+constexpr size_t align_down_4k(size_t v) noexcept {
+ return v & ~4095ULL;
+}
+
+bool env_var_is_yes(const char *env_var) noexcept {
+ const char *ev = getenv(env_var);
+ return ((ev != nullptr) && ("yes"sv == ev));
+}
+
+bool mprotect_trapping_is_enabled() noexcept {
+ static const bool enabled = (has_4k_pages() && env_var_is_yes("VESPA_USE_MPROTECT_TRAP"));
+ return enabled;
+}
+
+} // anon ns
+
+void MemoryRangeTrapper::rw_protect_buffer_if_possible() {
static_assert(std::is_same_v<size_t, uintptr_t>);
const auto aligned_start = align_up_4k(reinterpret_cast<uintptr_t>(_trap_buf));
const auto aligned_end = align_down_4k(reinterpret_cast<uintptr_t>(_trap_buf + _buf_len));
@@ -105,57 +126,34 @@ void MemoryRangeTrapper::rw_protect_buffer_if_possible() {
_trap_offset = _trap_len = 0;
}
}
-#endif
}
bool MemoryRangeTrapper::hw_trapping_enabled() noexcept {
-#ifdef VESPA_HAS_MPROTECT
return mprotect_trapping_is_enabled();
-#else
- return false;
-#endif
-}
-
-void MemoryRangeTrapper::check_and_release() noexcept {
- unprotect_buffer_to_read_only(); // Make sure sanity check can't race with writes
- verify_buffer_is_all_zeros();
- unprotect_buffer_to_read_and_write();
- _trap_len = _buf_len = 0;
}
void MemoryRangeTrapper::unprotect_buffer_to_read_only() {
-#ifdef VESPA_HAS_MPROTECT
if (_trap_len > 0) {
int ret = mprotect(_trap_buf + _trap_offset, _trap_len, PROT_READ);
assert(ret == 0 && "failed to un-protect memory region to PROT_READ");
}
-#endif
}
void MemoryRangeTrapper::unprotect_buffer_to_read_and_write() {
-#ifdef VESPA_HAS_MPROTECT
if (_trap_len > 0) {
int ret = mprotect(_trap_buf + _trap_offset, _trap_len, PROT_READ | PROT_WRITE);
assert(ret == 0 && "failed to un-protect memory region to PROT_READ | PROT_WRITE");
}
-#endif
}
-void MemoryRangeTrapper::verify_buffer_is_all_zeros() {
- for (size_t i = 0; i < _buf_len; ++i) {
- if (_trap_buf[i] != 0) {
- const bool in_protected_area = ((i >= _trap_offset) && (i < _trap_offset + _trap_len));
- LOG(error, "Memory corruption detected! Offset %zu into buffer %p: 0x%.2x != 0x00%s",
- i, _trap_buf, static_cast<unsigned int>(_trap_buf[i]),
- in_protected_area ? ". CORRUPTION IN R/W PROTECTED MEMORY!" : "");
- if (in_protected_area) {
- abort_due_to_PROTECTED_guard_bits_tampered_with();
- } else {
- abort_due_to_guard_bits_tampered_with();
- }
- }
- }
-}
+#else // VESPA_HAS_MPROTECT not defined, fall back to no-ops
+
+void MemoryRangeTrapper::rw_protect_buffer_if_possible() { /* no-op */ }
+bool MemoryRangeTrapper::hw_trapping_enabled() noexcept { return false; }
+void MemoryRangeTrapper::unprotect_buffer_to_read_only() { /* no-op */ }
+void MemoryRangeTrapper::unprotect_buffer_to_read_and_write() { /* no-op */ }
+
+#endif
HeapMemoryTrap::HeapMemoryTrap(size_t trap_4k_pages)
: _trap_buf(static_cast<char*>(memalign(4096, trap_4k_pages * 4096))),