pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
llvm-netbsd: extend Memory::allocateMappedMemory with PROT_MPROTECT
Module Name: pkgsrc-wip
Committed By: Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By: kamil
Date: Fri Jul 28 19:41:36 2017 +0200
Changeset: 2c2c9c438c587f377019d3e69ca349e8f66304c6
Modified Files:
llvm-netbsd/distinfo
Added Files:
llvm-netbsd/patches/patch-include_llvm_Support_Memory.h
llvm-netbsd/patches/patch-lib_Support_Unix_Memory.inc
llvm-netbsd/patches/patch-unittests_Support_MemoryTest.cpp
Log Message:
llvm-netbsd: extend Memory::allocateMappedMemory with PROT_MPROTECT
This is fixes Memory usage on NetBSD and creates ground for JIT allocator.
Sponsored by <The NetBSD Foundation>
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=2c2c9c438c587f377019d3e69ca349e8f66304c6
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
llvm-netbsd/distinfo | 3 +
.../patches/patch-include_llvm_Support_Memory.h | 55 +++++++++++++++++
.../patches/patch-lib_Support_Unix_Memory.inc | 68 ++++++++++++++++++++++
.../patches/patch-unittests_Support_MemoryTest.cpp | 63 ++++++++++++++++++++
4 files changed, 189 insertions(+)
diffs:
diff --git a/llvm-netbsd/distinfo b/llvm-netbsd/distinfo
index 7931384fd5..57bf92733e 100644
--- a/llvm-netbsd/distinfo
+++ b/llvm-netbsd/distinfo
@@ -12,3 +12,6 @@ Size (libcxx-3.6.2.src.tar.xz) = 944020 bytes
SHA1 (llvm-3.6.2.src.tar.xz) = 7a00257eb2bc9431e4c77c3a36b033072c54bc7e
RMD160 (llvm-3.6.2.src.tar.xz) = 521cbc5fe2925ea3c6e90c7a31f752a04045c972
Size (llvm-3.6.2.src.tar.xz) = 12802380 bytes
+SHA1 (patch-include_llvm_Support_Memory.h) = ba6eec99b1126ffbe27c18b63b3340697b192635
+SHA1 (patch-lib_Support_Unix_Memory.inc) = 69fc875b16e954e5fbf6fe2767d98c6f901713d4
+SHA1 (patch-unittests_Support_MemoryTest.cpp) = cd7bfc8053ceca839993e70e147cf803bac7eaae
diff --git a/llvm-netbsd/patches/patch-include_llvm_Support_Memory.h b/llvm-netbsd/patches/patch-include_llvm_Support_Memory.h
new file mode 100644
index 0000000000..1357346c9d
--- /dev/null
+++ b/llvm-netbsd/patches/patch-include_llvm_Support_Memory.h
@@ -0,0 +1,55 @@
+$NetBSD$
+
+--- include/llvm/Support/Memory.h.orig 2017-07-05 18:41:26.000000000 +0000
++++ include/llvm/Support/Memory.h
+@@ -36,6 +36,7 @@ namespace sys {
+ private:
+ void *Address; ///< Address of first byte of memory area
+ size_t Size; ///< Size, in bytes of the memory area
++ int MaxProtection;///< Maximum allowable Protection, of memory area
+ friend class Memory;
+ };
+
+@@ -61,16 +62,20 @@ namespace sys {
+ /// \p Flags is used to set the initial protection flags for the block
+ /// of the memory.
+ /// \p EC [out] returns an object describing any error that occurs.
++ /// \p MaxFlags is used to set the maximal protection flags for the block
++ /// of the memory. This value is OR'ed with \p Flags.
+ ///
+ /// This method may allocate more than the number of bytes requested. The
+ /// actual number of bytes allocated is indicated in the returned
+ /// MemoryBlock.
+ ///
+ /// The start of the allocated block must be aligned with the
+- /// system allocation granularity (64K on Windows, page size on Linux).
++ /// system allocation granularity (64K on Windows, page size on Linux, etc).
+ /// If the address following \p NearBlock is not so aligned, it will be
+ /// rounded up to the next allocation granularity boundary.
+ ///
++ /// For security reasons MF_WRITE | MF_EXEC mapping is prohibited.
++ ///
+ /// \r a non-null MemoryBlock if the function was successful,
+ /// otherwise a null MemoryBlock is with \p EC describing the error.
+ ///
+@@ -78,7 +83,7 @@ namespace sys {
+ static MemoryBlock allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned Flags,
+- std::error_code &EC);
++ std::error_code &EC, unsigned MaxFlags = 0);
+
+ /// This method releases a block of memory that was allocated with the
+ /// allocateMappedMemory method. It should not be used to release any
+@@ -102,6 +107,11 @@ namespace sys {
+ /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
+ /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
+ ///
++ /// The specified \p Flags parameter must by allowed by maximal protection
++ /// block of the memory.
++ ///
++ /// For security reasons MF_WRITE | MF_EXEC mapping is prohibited.
++ ///
+ /// \r error_success if the function was successful, or an error_code
+ /// describing the failure if an error occurred.
+ ///
diff --git a/llvm-netbsd/patches/patch-lib_Support_Unix_Memory.inc b/llvm-netbsd/patches/patch-lib_Support_Unix_Memory.inc
new file mode 100644
index 0000000000..a49693e9ea
--- /dev/null
+++ b/llvm-netbsd/patches/patch-lib_Support_Unix_Memory.inc
@@ -0,0 +1,68 @@
+$NetBSD$
+
+--- lib/Support/Unix/Memory.inc.orig 2017-07-05 18:38:14.000000000 +0000
++++ lib/Support/Unix/Memory.inc
+@@ -82,8 +82,16 @@ MemoryBlock
+ Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned PFlags,
+- std::error_code &EC) {
++ std::error_code &EC,
++ unsigned MaxPFlags) {
+ EC = std::error_code();
++
++ // W^X restriction
++ if ((PFlags & (MF_WRITE | MF_EXEC)) == (MF_WRITE | MF_EXEC)) {
++ EC = std::error_code(EACCES, std::generic_category());
++ return MemoryBlock();
++ }
++
+ if (NumBytes == 0)
+ return MemoryBlock();
+
+@@ -102,6 +110,13 @@ Memory::allocateMappedMemory(size_t NumB
+
+ int Protect = getPosixProtectionFlags(PFlags);
+
++ MaxPFlags |= PFlags;
++
++ // NetBSD with PaX MPROTECT must reserve additional allowable protection bits
++#if defined(__NetBSD__) && defined(PROT_MPROTECT)
++ Protect |= PROT_MPROTECT(getPosixProtectionFlags(MaxPFlags & (~PFlags)));
++#endif
++
+ // Use any near hint and the page size to set a page-aligned starting address
+ uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
+ NearBlock->size() : 0;
+@@ -112,7 +127,7 @@ Memory::allocateMappedMemory(size_t NumB
+ Protect, MMFlags, fd, 0);
+ if (Addr == MAP_FAILED) {
+ if (NearBlock) //Try again without a near hint
+- return allocateMappedMemory(NumBytes, nullptr, PFlags, EC);
++ return allocateMappedMemory(NumBytes, nullptr, PFlags, EC, MaxPFlags);
+
+ EC = std::error_code(errno, std::generic_category());
+ return MemoryBlock();
+@@ -121,6 +136,7 @@ Memory::allocateMappedMemory(size_t NumB
+ MemoryBlock Result;
+ Result.Address = Addr;
+ Result.Size = NumPages*PageSize;
++ Result.MaxProtection = MaxPFlags;
+
+ if (PFlags & MF_EXEC)
+ Memory::InvalidateInstructionCache(Result.Address, Result.Size);
+@@ -144,6 +160,14 @@ Memory::releaseMappedMemory(MemoryBlock
+
+ std::error_code
+ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
++ // W^X restriction
++ if ((Flags & (MF_WRITE | MF_EXEC)) == (MF_WRITE | MF_EXEC))
++ return std::error_code(EACCES, std::generic_category());
++
++ // Check whether new protection bits are allowed
++ if ((~M.MaxProtection) & Flags)
++ return std::error_code(EACCES, std::generic_category());
++
+ static const size_t PageSize = Process::getPageSize();
+ if (M.Address == nullptr || M.Size == 0)
+ return std::error_code();
diff --git a/llvm-netbsd/patches/patch-unittests_Support_MemoryTest.cpp b/llvm-netbsd/patches/patch-unittests_Support_MemoryTest.cpp
new file mode 100644
index 0000000000..c7ce025a70
--- /dev/null
+++ b/llvm-netbsd/patches/patch-unittests_Support_MemoryTest.cpp
@@ -0,0 +1,63 @@
+$NetBSD$
+
+--- unittests/Support/MemoryTest.cpp.orig 2017-07-05 18:41:47.000000000 +0000
++++ unittests/Support/MemoryTest.cpp
+@@ -33,9 +33,8 @@ protected:
+ case Memory::MF_READ|Memory::MF_WRITE:
+ return Memory::MF_READ|Memory::MF_WRITE;
+ case Memory::MF_READ|Memory::MF_EXEC:
+- case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
+ case Memory::MF_EXEC:
+- return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
++ return Memory::MF_READ|Memory::MF_EXEC;
+ }
+ // Default in case values are added to the enum, as required by some compilers
+ return Memory::MF_READ|Memory::MF_WRITE;
+@@ -181,14 +180,19 @@ TEST_P(MappedMemoryTest, MultipleWrite)
+
+ TEST_P(MappedMemoryTest, EnabledWrite) {
+ std::error_code EC;
++
++ // W^R restriction
++ if (Flags & Memory::MF_EXEC)
++ return;
++
+ MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
+- EC);
++ EC, getTestableEquivalent(Flags));
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
+- EC);
++ EC, getTestableEquivalent(Flags));
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
+- EC);
++ EC, getTestableEquivalent(Flags));
+ EXPECT_EQ(std::error_code(), EC);
+
+ EXPECT_NE((void*)nullptr, M1.base());
+@@ -223,7 +227,7 @@ TEST_P(MappedMemoryTest, EnabledWrite) {
+ EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+ EXPECT_EQ(6, y[6]);
+
+- MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
++ MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC, getTestableEquivalent(Flags));
+ EXPECT_EQ(std::error_code(), EC);
+ EXPECT_NE((void*)nullptr, M4.base());
+ EXPECT_LE(16U, M4.size());
+@@ -349,13 +353,13 @@ TEST_P(MappedMemoryTest, UnalignedNear)
+
+ // Note that Memory::MF_WRITE is not supported exclusively across
+ // operating systems and architectures and can imply MF_READ|MF_WRITE
++// RWX mapping is not allowed (W^X restrictions)
+ unsigned MemoryFlags[] = {
+ Memory::MF_READ,
+ Memory::MF_WRITE,
+ Memory::MF_READ|Memory::MF_WRITE,
+ Memory::MF_EXEC,
+- Memory::MF_READ|Memory::MF_EXEC,
+- Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
++ Memory::MF_READ|Memory::MF_EXEC
+ };
+
+ INSTANTIATE_TEST_CASE_P(AllocationTests,
Home |
Main Index |
Thread Index |
Old Index