From 960733099b0e3334be7af26531d81f45cf1f10b7 Mon Sep 17 00:00:00 2001 From: Nathaniel Filardo Date: Thu, 14 Jan 2021 16:32:32 +0000 Subject: [PATCH] POSIX PAL: reset errno on failing mmap()s for zeroing We try, if the region to be zeroed is sufficiently aligned, to use mmap to swap out pages for zeros. --- src/pal/pal_posix.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/pal/pal_posix.h b/src/pal/pal_posix.h index cca67a6..9e38c36 100644 --- a/src/pal/pal_posix.h +++ b/src/pal/pal_posix.h @@ -4,6 +4,7 @@ #if defined(BACKTRACE_HEADER) # include BACKTRACE_HEADER #endif +#include #include #include #include @@ -89,6 +90,22 @@ namespace snmalloc static const int fd = T::anonymous_memory_fd; }; + /** + * A RAII class to capture and restore errno + */ + class KeepErrno + { + decltype(errno) cached_errno; + + public: + KeepErrno() : cached_errno(errno) {} + + ~KeepErrno() + { + errno = cached_errno; + } + }; + public: /** * Bitmap of PalFeatures flags indicating the optional features that this @@ -186,6 +203,16 @@ namespace snmalloc if (page_aligned || is_aligned_block(p, size)) { SNMALLOC_ASSERT(is_aligned_block(p, size)); + + /* + * If mmap fails, we're going to fall back to zeroing the memory + * ourselves, which is not stellar, but correct. However, mmap() will + * have has left errno nonzero in an effort to explain its MAP_FAILED + * result. Capture its current value and restore it at the end of this + * block. + */ + auto hold = KeepErrno(); + void* r = mmap( p, size,