[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