From 179f09081f3d2eaa2d00235858cfd70c4030b5ee Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 12 Dec 2020 21:32:36 +0700 Subject: [PATCH] Alternative secure JIT for macOS. --- src/crypto/common/VirtualMemory_unix.cpp | 17 +++++++++++++++-- src/crypto/randomx/jit_compiler_a64.cpp | 19 +++++++++++++------ src/crypto/randomx/jit_compiler_a64.hpp | 3 ++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index ba2da31b7..1c114b828 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -30,6 +30,7 @@ #ifdef XMRIG_OS_APPLE # include # include +# include # include # ifdef XMRIG_OS_MACOS # define MEXTRA MAP_JIT @@ -74,7 +75,12 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable() bool xmrig::VirtualMemory::protectRW(void *p, size_t size) { +# if defined(XMRIG_OS_APPLE) && defined(XMRIG_ARM) + pthread_jit_write_protect_np(false); + return true; +# else return mprotect(p, size, PROT_READ | PROT_WRITE) == 0; +# endif } @@ -86,14 +92,21 @@ bool xmrig::VirtualMemory::protectRWX(void *p, size_t size) bool xmrig::VirtualMemory::protectRX(void *p, size_t size) { +# if defined(XMRIG_OS_APPLE) && defined(XMRIG_ARM) + pthread_jit_write_protect_np(true); + flushInstructionCache(p, size); + return true; +# else return mprotect(p, size, PROT_READ | PROT_EXEC) == 0; +# endif } void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages) { -# if defined(__APPLE__) - void *mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANON | MEXTRA, -1, 0); +# if defined(XMRIG_OS_APPLE) + void *mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON | MEXTRA, -1, 0); + pthread_jit_write_protect_np(false); # elif defined(__FreeBSD__) void *mem = nullptr; diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index d61e20b5c..b38491db2 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -99,17 +99,18 @@ static size_t CalcDatasetItemSize() constexpr uint32_t IntRegMap[8] = { 4, 5, 6, 7, 12, 13, 14, 15 }; JitCompilerA64::JitCompilerA64(bool hugePagesEnable) - : code((uint8_t*) allocExecutableMemory(CodeSize + CalcDatasetItemSize(), hugePagesJIT && hugePagesEnable)) - , literalPos(ImulRcpLiteralsEnd) - , num32bitLiterals(0) + : literalPos(ImulRcpLiteralsEnd) { + allocatedSize = CodeSize + CalcDatasetItemSize(); + code = static_cast(allocExecutableMemory(allocatedSize, hugePagesJIT && hugePagesEnable)); + memset(reg_changed_offset, 0, sizeof(reg_changed_offset)); memcpy(code, (void*) randomx_program_aarch64, CodeSize); } JitCompilerA64::~JitCompilerA64() { - freePagedMemory(code, CodeSize + CalcDatasetItemSize()); + freePagedMemory(code, allocatedSize); } void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t) @@ -162,7 +163,9 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con codePos = ((uint8_t*)randomx_program_aarch64_update_spMix1) - ((uint8_t*)randomx_program_aarch64); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); +# ifndef XMRIG_OS_APPLE xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); +# endif } void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) @@ -217,7 +220,9 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration emit32(ARMV8A::ADD_IMM_LO | 2 | (2 << 5) | (imm_lo << 10), code, codePos); emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos); +# ifndef XMRIG_OS_APPLE xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); +# endif } template @@ -333,7 +338,9 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) memcpy(code + codePos, p1, p2 - p1); codePos += p2 - p1; +# ifndef XMRIG_OS_APPLE xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + CodeSize), reinterpret_cast(code + codePos)); +# endif } template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]); @@ -354,12 +361,12 @@ size_t JitCompilerA64::getCodeSize() void JitCompilerA64::enableWriting() const { - xmrig::VirtualMemory::protectRW(code, CodeSize + CalcDatasetItemSize()); + xmrig::VirtualMemory::protectRW(code, allocatedSize); } void JitCompilerA64::enableExecution() const { - xmrig::VirtualMemory::protectRX(code, CodeSize + CalcDatasetItemSize()); + xmrig::VirtualMemory::protectRX(code, allocatedSize); } void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos) diff --git a/src/crypto/randomx/jit_compiler_a64.hpp b/src/crypto/randomx/jit_compiler_a64.hpp index 3f5b9a980..1e8063de8 100644 --- a/src/crypto/randomx/jit_compiler_a64.hpp +++ b/src/crypto/randomx/jit_compiler_a64.hpp @@ -80,7 +80,8 @@ namespace randomx { uint32_t reg_changed_offset[8]; uint8_t* code; uint32_t literalPos; - uint32_t num32bitLiterals; + uint32_t num32bitLiterals = 0; + size_t allocatedSize = 0; static void emit32(uint32_t val, uint8_t* code, uint32_t& codePos) {