Alternative secure JIT for macOS.

This commit is contained in:
XMRig 2020-12-12 21:32:36 +07:00
parent 775867fc3e
commit 179f09081f
No known key found for this signature in database
GPG key ID: 446A53638BE94409
3 changed files with 30 additions and 9 deletions

View file

@ -30,6 +30,7 @@
#ifdef XMRIG_OS_APPLE #ifdef XMRIG_OS_APPLE
# include <libkern/OSCacheControl.h> # include <libkern/OSCacheControl.h>
# include <mach/vm_statistics.h> # include <mach/vm_statistics.h>
# include <pthread.h>
# include <TargetConditionals.h> # include <TargetConditionals.h>
# ifdef XMRIG_OS_MACOS # ifdef XMRIG_OS_MACOS
# define MEXTRA MAP_JIT # define MEXTRA MAP_JIT
@ -74,7 +75,12 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable()
bool xmrig::VirtualMemory::protectRW(void *p, size_t size) 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; 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) 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; return mprotect(p, size, PROT_READ | PROT_EXEC) == 0;
# endif
} }
void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages) void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages)
{ {
# if defined(__APPLE__) # if defined(XMRIG_OS_APPLE)
void *mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANON | MEXTRA, -1, 0); 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__) # elif defined(__FreeBSD__)
void *mem = nullptr; void *mem = nullptr;

View file

@ -99,17 +99,18 @@ static size_t CalcDatasetItemSize()
constexpr uint32_t IntRegMap[8] = { 4, 5, 6, 7, 12, 13, 14, 15 }; constexpr uint32_t IntRegMap[8] = { 4, 5, 6, 7, 12, 13, 14, 15 };
JitCompilerA64::JitCompilerA64(bool hugePagesEnable) JitCompilerA64::JitCompilerA64(bool hugePagesEnable)
: code((uint8_t*) allocExecutableMemory(CodeSize + CalcDatasetItemSize(), hugePagesJIT && hugePagesEnable)) : literalPos(ImulRcpLiteralsEnd)
, literalPos(ImulRcpLiteralsEnd)
, num32bitLiterals(0)
{ {
allocatedSize = CodeSize + CalcDatasetItemSize();
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePagesJIT && hugePagesEnable));
memset(reg_changed_offset, 0, sizeof(reg_changed_offset)); memset(reg_changed_offset, 0, sizeof(reg_changed_offset));
memcpy(code, (void*) randomx_program_aarch64, CodeSize); memcpy(code, (void*) randomx_program_aarch64, CodeSize);
} }
JitCompilerA64::~JitCompilerA64() JitCompilerA64::~JitCompilerA64()
{ {
freePagedMemory(code, CodeSize + CalcDatasetItemSize()); freePagedMemory(code, allocatedSize);
} }
void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t) 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); 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); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
# endif
} }
void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) 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_LO | 2 | (2 << 5) | (imm_lo << 10), code, codePos);
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 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<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
# endif
} }
template<size_t N> template<size_t N>
@ -333,7 +338,9 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
memcpy(code + codePos, p1, p2 - p1); memcpy(code + codePos, p1, p2 - p1);
codePos += p2 - p1; codePos += p2 - p1;
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
# endif
} }
template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]); template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
@ -354,12 +361,12 @@ size_t JitCompilerA64::getCodeSize()
void JitCompilerA64::enableWriting() const void JitCompilerA64::enableWriting() const
{ {
xmrig::VirtualMemory::protectRW(code, CodeSize + CalcDatasetItemSize()); xmrig::VirtualMemory::protectRW(code, allocatedSize);
} }
void JitCompilerA64::enableExecution() const 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) void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos)

View file

@ -80,7 +80,8 @@ namespace randomx {
uint32_t reg_changed_offset[8]; uint32_t reg_changed_offset[8];
uint8_t* code; uint8_t* code;
uint32_t literalPos; 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) static void emit32(uint32_t val, uint8_t* code, uint32_t& codePos)
{ {