[tor-commits] [tor/maint-0.4.1] madvise: tolerate EINVAL and ENOSYS when minherit fails

nickm at torproject.org nickm at torproject.org
Tue Sep 17 22:53:19 UTC 2019


commit 0891a31ad32d0567fbc8f73a0598925cb543d699
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Sep 11 09:13:50 2019 -0400

    madvise: tolerate EINVAL and ENOSYS when minherit fails
    
    These errors can occur if we are built on a system with support for
    madvise(MADV_NOFORK) but then we are run on a system whose kernel
    does not support that flag.
    
    If the error is something that we don't tolerate at all, we now log
    it before crashing.
    
    Fixes bug 31696.  I am calling this a bugfix on 0.4.1.1-alpha, where
    we actually started using the map_anon code.
    
    This is similar to, but not the same as, the fix for #31570.
---
 changes/bug31696          |  5 +++++
 src/lib/malloc/map_anon.c | 24 +++++++++++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/changes/bug31696 b/changes/bug31696
new file mode 100644
index 000000000..b9d6c4130
--- /dev/null
+++ b/changes/bug31696
@@ -0,0 +1,5 @@
+  o Major bugfixes (crash, Linux):
+    - Tolerate systems (including some Linux installations) where madvise
+      and/or MADV_DONTFORK are available at build-time, but not at run time.
+      Previously, these systems would notice a failed syscall and abort.
+      Fixes bug 31696; bugfix on 0.4.1.1-alpha.
diff --git a/src/lib/malloc/map_anon.c b/src/lib/malloc/map_anon.c
index 0f6a4150c..08b754540 100644
--- a/src/lib/malloc/map_anon.c
+++ b/src/lib/malloc/map_anon.c
@@ -27,6 +27,9 @@
 #include <windows.h>
 #endif
 
+#include <string.h>
+#include <errno.h>
+
 /**
  * Macro to get the high bytes of a size_t, if there are high bytes.
  * Windows needs this; other operating systems define a size_t that does
@@ -136,18 +139,33 @@ noinherit_mem(void *mem, size_t sz, inherit_res_t *inherit_result_out)
     return 0;
   }
 #endif /* defined(FLAG_ZERO) */
+
 #ifdef FLAG_NOINHERIT
   int r2 = MINHERIT(mem, sz, FLAG_NOINHERIT);
   if (r2 == 0) {
     *inherit_result_out = INHERIT_RES_DROP;
+    return 0;
   }
-  return r2;
-#else /* !(defined(FLAG_NOINHERIT)) */
+#endif /* defined(FLAG_NOINHERIT) */
+
+#if defined(FLAG_ZERO) || defined(FLAG_NOINHERIT)
+  /* At least one operation was tried, and neither succeeded. */
+
+  if (errno == ENOSYS || errno == EINVAL) {
+    /* Syscall not supported, or flag not supported. */
+    return 0;
+  } else {
+    tor_log_err_sigsafe("Unexpected error from minherit: ",
+                        strerror(errno),
+                        NULL);
+    return -1;
+  }
+#else
   (void)inherit_result_out;
   (void)mem;
   (void)sz;
   return 0;
-#endif /* defined(FLAG_NOINHERIT) */
+#endif
 }
 
 /**



More information about the tor-commits mailing list