Skip to content

Commit

Permalink
[unittest] Skip W+X MappedMemoryTests when MPROTECT is enabled
Browse files Browse the repository at this point in the history
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

llvm-svn: 347337
  • Loading branch information
mgorny committed Nov 20, 2018
1 parent afedb89 commit 1b25ba0
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions llvm/unittests/Support/MemoryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -56,7 +86,16 @@ class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 1b25ba0

Please sign in to comment.