[llvm] r347337 - [unittest] Skip W+X MappedMemoryTests when MPROTECT is enabled

Michal Gorny via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 20 10:38:12 PST 2018


Author: mgorny
Date: Tue Nov 20 10:38:11 2018
New Revision: 347337

URL: http://llvm.org/viewvc/llvm-project?rev=347337&view=rev
Log:
[unittest] Skip W+X MappedMemoryTests when MPROTECT is enabled

Skip all MappedMemoryTest variants that rely on memory pages being
mapped for MF_WRITE|MF_EXEC when MPROTECT is enabled on NetBSD.  W^X
protection causes all those mmap() calls to fail, causing the tests
to fail.

Differential Revision: https://reviews.llvm.org/D54080

Modified:
    llvm/trunk/unittests/Support/MemoryTest.cpp

Modified: llvm/trunk/unittests/Support/MemoryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/MemoryTest.cpp?rev=347337&r1=347336&r2=347337&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/MemoryTest.cpp (original)
+++ llvm/trunk/unittests/Support/MemoryTest.cpp Tue Nov 20 10:38:11 2018
@@ -10,13 +10,43 @@
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/Process.h"
 #include "gtest/gtest.h"
+#include <cassert>
 #include <cstdlib>
 
+#if defined(__NetBSD__)
+// clang-format off
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#include <unistd.h>
+// clang-format on
+#endif
+
 using namespace llvm;
 using namespace sys;
 
 namespace {
 
+bool IsMPROTECT() {
+#if defined(__NetBSD__)
+  int mib[3];
+  int paxflags;
+  size_t len = sizeof(paxflags);
+
+  mib[0] = CTL_PROC;
+  mib[1] = getpid();
+  mib[2] = PROC_PID_PAXFLAGS;
+
+  if (sysctl(mib, 3, &paxflags, &len, NULL, 0) != 0)
+    err(EXIT_FAILURE, "sysctl");
+
+  return !!(paxflags & CTL_PROC_PAXFLAGS_MPROTECT);
+#else
+  return false;
+#endif
+}
+
 class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
 public:
   MappedMemoryTest() {
@@ -56,7 +86,16 @@ protected:
   size_t   PageSize;
 };
 
+// MPROTECT prevents W+X mmaps
+#define CHECK_UNSUPPORTED() \
+  do { \
+    if ((Flags & Memory::MF_WRITE) && (Flags & Memory::MF_EXEC) && \
+        IsMPROTECT()) \
+      return; \
+  } while (0)
+
 TEST_P(MappedMemoryTest, AllocAndRelease) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
   EXPECT_EQ(std::error_code(), EC);
@@ -68,6 +107,7 @@ TEST_P(MappedMemoryTest, AllocAndRelease
 }
 
 TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
   EXPECT_EQ(std::error_code(), EC);
@@ -102,6 +142,7 @@ TEST_P(MappedMemoryTest, BasicWrite) {
   if (Flags &&
       !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
     return;
+  CHECK_UNSUPPORTED();
 
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
@@ -122,6 +163,8 @@ TEST_P(MappedMemoryTest, MultipleWrite)
   if (Flags &&
       !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
     return;
+  CHECK_UNSUPPORTED();
+
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
                                                 EC);
@@ -180,6 +223,11 @@ TEST_P(MappedMemoryTest, MultipleWrite)
 }
 
 TEST_P(MappedMemoryTest, EnabledWrite) {
+  // MPROTECT prevents W+X, and since this test always adds W we need
+  // to block any variant with X.
+  if ((Flags & Memory::MF_EXEC) && IsMPROTECT())
+    return;
+
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
                                                 EC);
@@ -237,6 +285,7 @@ TEST_P(MappedMemoryTest, EnabledWrite) {
 }
 
 TEST_P(MappedMemoryTest, SuccessiveNear) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
   EXPECT_EQ(std::error_code(), EC);
@@ -262,6 +311,7 @@ TEST_P(MappedMemoryTest, SuccessiveNear)
 }
 
 TEST_P(MappedMemoryTest, DuplicateNear) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock Near((void*)(3*PageSize), 16);
   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
@@ -284,6 +334,7 @@ TEST_P(MappedMemoryTest, DuplicateNear)
 }
 
 TEST_P(MappedMemoryTest, ZeroNear) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock Near(nullptr, 0);
   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
@@ -310,6 +361,7 @@ TEST_P(MappedMemoryTest, ZeroNear) {
 }
 
 TEST_P(MappedMemoryTest, ZeroSizeNear) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock Near((void*)(4*PageSize), 0);
   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
@@ -336,6 +388,7 @@ TEST_P(MappedMemoryTest, ZeroSizeNear) {
 }
 
 TEST_P(MappedMemoryTest, UnalignedNear) {
+  CHECK_UNSUPPORTED();
   std::error_code EC;
   MemoryBlock Near((void*)(2*PageSize+5), 0);
   MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);




More information about the llvm-commits mailing list