From ec62ded279a8397af13d007664930b2b0c633308 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 11 Dec 2020 23:17:54 +0700 Subject: [PATCH] Added generic secure JIT support for RandomX. --- CMakeLists.txt | 3 +- cmake/os.cmake | 8 +++ src/3rdparty/argon2/CMakeLists.txt | 2 +- src/3rdparty/libethash/CMakeLists.txt | 2 +- src/backend/backend.cmake | 8 +-- src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 9 ++- src/crypto/cn/CnHash.cpp | 2 +- src/crypto/common/VirtualMemory.cpp | 13 +--- src/crypto/common/VirtualMemory.h | 18 ++--- src/crypto/common/VirtualMemory_unix.cpp | 70 +++++++++++-------- src/crypto/common/VirtualMemory_win.cpp | 62 +++++++++------- src/crypto/randomx/dataset.cpp | 21 ++++-- src/crypto/randomx/jit_compiler_a64.cpp | 23 +++++- src/crypto/randomx/jit_compiler_a64.hpp | 9 ++- src/crypto/randomx/jit_compiler_fallback.hpp | 7 +- src/crypto/randomx/jit_compiler_x86.cpp | 36 +++++++--- src/crypto/randomx/jit_compiler_x86.hpp | 7 +- src/crypto/randomx/vm_compiled.cpp | 14 +++- src/crypto/randomx/vm_compiled_light.cpp | 23 +++++- 19 files changed, 227 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bed2ca48..6d13ca472 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(xmrig) option(WITH_HWLOC "Enable hwloc support" ON) @@ -25,6 +25,7 @@ option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF) option(WITH_PROFILING "Enable profiling for developers" OFF) option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON) option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON) +option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF) option(BUILD_STATIC "Build static binary" OFF) option(ARM_TARGET "Force use specific ARM target 8 or 7" 0) diff --git a/cmake/os.cmake b/cmake/os.cmake index 0270cc930..099311030 100644 --- a/cmake/os.cmake +++ b/cmake/os.cmake @@ -32,6 +32,10 @@ elseif(XMRIG_OS_APPLE) else() add_definitions(/DXMRIG_OS_MACOS) endif() + + if (XMRIG_ARM) + set(WITH_SECURE_JIT ON) + endif() elseif(XMRIG_OS_UNIX) add_definitions(/DXMRIG_OS_UNIX) @@ -43,3 +47,7 @@ elseif(XMRIG_OS_UNIX) add_definitions(/DXMRIG_OS_FREEBSD) endif() endif() + +if (WITH_SECURE_JIT) + add_definitions(/DXMRIG_SECURE_JIT) +endif() diff --git a/src/3rdparty/argon2/CMakeLists.txt b/src/3rdparty/argon2/CMakeLists.txt index 2f1fc0a90..e02197be8 100644 --- a/src/3rdparty/argon2/CMakeLists.txt +++ b/src/3rdparty/argon2/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(argon2 C) set(CMAKE_C_STANDARD 99) diff --git a/src/3rdparty/libethash/CMakeLists.txt b/src/3rdparty/libethash/CMakeLists.txt index 2fd2f4371..6a5454409 100644 --- a/src/3rdparty/libethash/CMakeLists.txt +++ b/src/3rdparty/libethash/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 2.8.12) project (ethash C) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") diff --git a/src/backend/backend.cmake b/src/backend/backend.cmake index 6bf6c3b20..73dd8605d 100644 --- a/src/backend/backend.cmake +++ b/src/backend/backend.cmake @@ -1,7 +1,7 @@ -include (src/backend/cpu/cpu.cmake) -include (src/backend/opencl/opencl.cmake) -include (src/backend/cuda/cuda.cmake) -include (src/backend/common/common.cmake) +include(src/backend/cpu/cpu.cmake) +include(src/backend/opencl/opencl.cmake) +include(src/backend/cuda/cuda.cmake) +include(src/backend/common/common.cmake) set(HEADERS_BACKEND diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index a2b336a5d..ea6db3f1e 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -36,12 +36,14 @@ #include "3rdparty/rapidjson/document.h" -#ifdef XMRIG_OS_UNIX +#if defined(XMRIG_OS_UNIX) namespace xmrig { extern String cpu_name_arm(); } // namespace xmrig +#elif defined(XMRIG_OS_MACOS) +# include #endif @@ -62,13 +64,16 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : # endif # endif -# ifdef XMRIG_OS_UNIX +# if defined(XMRIG_OS_UNIX) auto name = cpu_name_arm(); if (!name.isNull()) { strncpy(m_brand, name, sizeof(m_brand) - 1); } m_flags.set(FLAG_PDPE1GB, std::ifstream("/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages").good()); +# elif defined(XMRIG_OS_MACOS) + size_t buflen = sizeof(m_brand); + sysctlbyname("machdep.cpu.brand_string", &m_brand, &buflen, nullptr, 0); # endif } diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp index d11202a4f..9a9e5ea5f 100644 --- a/src/crypto/cn/CnHash.cpp +++ b/src/crypto/cn/CnHash.cpp @@ -219,7 +219,7 @@ static void patchAsmVariants() patchCode(cn_double_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER); } - VirtualMemory::protectExecutableMemory(base, allocation_size); + VirtualMemory::protectRX(base, allocation_size); VirtualMemory::flushInstructionCache(base, allocation_size); } } // namespace xmrig diff --git a/src/crypto/common/VirtualMemory.cpp b/src/crypto/common/VirtualMemory.cpp index b34e6de0e..7d8d980b2 100644 --- a/src/crypto/common/VirtualMemory.cpp +++ b/src/crypto/common/VirtualMemory.cpp @@ -1,14 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 tevador - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2020 tevador + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index 1bfdab805..a7f03e0fb 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -1,14 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 tevador - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2020 tevador + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,6 +53,9 @@ public: static bool isHugepagesAvailable(); static bool isOneGbPagesAvailable(); + static bool protectRW(void *p, size_t size); + static bool protectRWX(void *p, size_t size); + static bool protectRX(void *p, size_t size); static uint32_t bindToNUMANode(int64_t affinity); static void *allocateExecutableMemory(size_t size, bool hugePages); static void *allocateLargePagesMemory(size_t size); @@ -68,8 +64,6 @@ public: static void flushInstructionCache(void *p, size_t size); static void freeLargePagesMemory(void *p, size_t size); static void init(size_t poolSize, bool hugePages); - static void protectExecutableMemory(void *p, size_t size); - static void unprotectExecutableMemory(void *p, size_t size); static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index 70bb13d52..a523ea762 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -1,14 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2018-2019 tevador - * Copyright 2016-2019 XMRig , + * Copyright (c) 2018-2020 tevador + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,8 +27,16 @@ #include "crypto/common/VirtualMemory.h" -#if defined(__APPLE__) +#ifdef __APPLE__ +# include # include +# ifdef XMRIG_OS_MACOS +# define MEXTRA MAP_JIT +# else +# define MEXTRA 0 +# endif +#else +# define MEXTRA 0 #endif @@ -47,6 +48,13 @@ #endif +#ifdef XMRIG_SECURE_JIT +# define SECURE_PROT_EXEC 0 +#else +# define SECURE_PROT_EXEC PROT_EXEC +#endif + + bool xmrig::VirtualMemory::isHugepagesAvailable() { return true; @@ -63,19 +71,37 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable() } +bool xmrig::VirtualMemory::protectRW(void *p, size_t size) +{ + return mprotect(p, size, PROT_READ | PROT_WRITE) == 0; +} + + +bool xmrig::VirtualMemory::protectRWX(void *p, size_t size) +{ + return mprotect(p, size, PROT_READ | PROT_WRITE | PROT_EXEC) == 0; +} + + +bool xmrig::VirtualMemory::protectRX(void *p, size_t size) +{ + return mprotect(p, size, PROT_READ | PROT_EXEC) == 0; +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages) { # if defined(__APPLE__) - void *mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); + void *mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANON | MEXTRA, -1, 0); # elif defined(__FreeBSD__) void *mem = nullptr; if (hugePages) { - mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0); + mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0); } if (!mem) { - mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } # else @@ -91,11 +117,11 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages void *mem = nullptr; if (hugePages) { - mem = mmap(0, align(size), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0); + mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0); } if (!mem) { - mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } # endif @@ -164,18 +190,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size) } -void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size) -{ - mprotect(p, size, PROT_READ | PROT_EXEC); -} - - -void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size) -{ - mprotect(p, size, PROT_WRITE | PROT_EXEC); -} - - void xmrig::VirtualMemory::osInit(bool) { } diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index 9bee37ffe..fee5f5852 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -1,14 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2018-2019 tevador - * Copyright 2016-2019 XMRig , + * Copyright (c) 2018-2020 tevador + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,6 +29,13 @@ #include "crypto/common/VirtualMemory.h" +#ifdef XMRIG_SECURE_JIT +# define SECURE_PAGE_EXECUTE_READWRITE PAGE_READWRITE +#else +# define SECURE_PAGE_EXECUTE_READWRITE PAGE_EXECUTE_READWRITE +#endif + + namespace xmrig { @@ -162,16 +162,40 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable() } +bool xmrig::VirtualMemory::protectRW(void *p, size_t size) +{ + DWORD oldProtect; + + return VirtualProtect(p, size, PAGE_READWRITE, &oldProtect) != 0; +} + + +bool xmrig::VirtualMemory::protectRWX(void *p, size_t size) +{ + DWORD oldProtect; + + return VirtualProtect(p, size, PAGE_EXECUTE_READWRITE, &oldProtect) != 0; +} + + +bool xmrig::VirtualMemory::protectRX(void *p, size_t size) +{ + DWORD oldProtect; + + return VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect) != 0; +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages) { void* result = nullptr; if (hugePages) { - result = VirtualAlloc(nullptr, align(size), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_EXECUTE_READWRITE); + result = VirtualAlloc(nullptr, align(size), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, SECURE_PAGE_EXECUTE_READWRITE); } if (!result) { - result = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + result = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, SECURE_PAGE_EXECUTE_READWRITE); } return result; @@ -209,20 +233,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t) } -void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size) -{ - DWORD oldProtect; - VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect); -} - - -void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size) -{ - DWORD oldProtect; - VirtualProtect(p, size, PAGE_EXECUTE_READWRITE, &oldProtect); -} - - void xmrig::VirtualMemory::osInit(bool hugePages) { if (hugePages) { diff --git a/src/crypto/randomx/dataset.cpp b/src/crypto/randomx/dataset.cpp index ade6f2b75..9215cd59a 100644 --- a/src/crypto/randomx/dataset.cpp +++ b/src/crypto/randomx/dataset.cpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -77,16 +79,16 @@ namespace randomx { context.pwdlen = (uint32_t)keySize; context.salt = CONST_CAST(uint8_t *)RandomX_CurrentConfig.ArgonSalt; context.saltlen = (uint32_t)strlen(RandomX_CurrentConfig.ArgonSalt); - context.secret = NULL; + context.secret = nullptr; context.secretlen = 0; - context.ad = NULL; + context.ad = nullptr; context.adlen = 0; context.t_cost = RandomX_CurrentConfig.ArgonIterations; context.m_cost = RandomX_CurrentConfig.ArgonMemory; context.lanes = RandomX_CurrentConfig.ArgonLanes; context.threads = 1; - context.allocate_cbk = NULL; - context.free_cbk = NULL; + context.allocate_cbk = nullptr; + context.free_cbk = nullptr; context.flags = ARGON2_DEFAULT_FLAGS; context.version = ARGON2_VERSION_NUMBER; @@ -100,8 +102,17 @@ namespace randomx { void initCacheCompile(randomx_cache* cache, const void* key, size_t keySize) { initCache(cache, key, keySize); + +# ifdef XMRIG_SECURE_JIT + cache->jit->enableWriting(); +# endif + cache->jit->generateSuperscalarHash(cache->programs); cache->jit->generateDatasetInitCode(); + +# ifdef XMRIG_SECURE_JIT + cache->jit->enableExecution(); +# endif } constexpr uint64_t superscalarMul0 = 6364136223846793005ULL; diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index e4072381b..4d9a34cae 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -1,6 +1,7 @@ /* -Copyright (c) 2018-2019, tevador -Copyright (c) 2019, SChernykh +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -28,9 +29,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto/randomx/jit_compiler_a64.hpp" -#include "crypto/randomx/superscalar.hpp" +#include "crypto/common/VirtualMemory.h" #include "crypto/randomx/program.hpp" #include "crypto/randomx/reciprocal.h" +#include "crypto/randomx/superscalar.hpp" #include "crypto/randomx/virtual_memory.hpp" static bool hugePagesJIT = false; @@ -357,6 +359,21 @@ size_t JitCompilerA64::getCodeSize() return CodeSize; } +void JitCompilerA64::enableWriting() +{ + xmrig::VirtualMemory::protectRW(code, CodeSize + CalcDatasetItemSize()); +} + +void JitCompilerA64::enableExecution() +{ + xmrig::VirtualMemory::protectRX(code, CodeSize + CalcDatasetItemSize()); +} + +void JitCompilerA64::enableAll() +{ + xmrig::VirtualMemory::protectRWX(code, CodeSize + CalcDatasetItemSize()); +} + void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos) { uint32_t k = codePos; diff --git a/src/crypto/randomx/jit_compiler_a64.hpp b/src/crypto/randomx/jit_compiler_a64.hpp index 29ce478d5..3b47ea3a4 100644 --- a/src/crypto/randomx/jit_compiler_a64.hpp +++ b/src/crypto/randomx/jit_compiler_a64.hpp @@ -1,6 +1,7 @@ /* -Copyright (c) 2018-2019, tevador -Copyright (c) 2019, SChernykh +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -63,6 +64,10 @@ namespace randomx { uint8_t* getCode() { return code; } size_t getCodeSize(); + void enableWriting(); + void enableExecution(); + void enableAll(); + static InstructionGeneratorA64 engine[256]; uint32_t reg_changed_offset[8]; uint8_t* code; diff --git a/src/crypto/randomx/jit_compiler_fallback.hpp b/src/crypto/randomx/jit_compiler_fallback.hpp index 7f643b174..0eb4058ff 100644 --- a/src/crypto/randomx/jit_compiler_fallback.hpp +++ b/src/crypto/randomx/jit_compiler_fallback.hpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -70,5 +72,8 @@ namespace randomx { size_t getCodeSize() { return 0; } + void enableWriting() {} + void enableExecution() {} + void enableAll() {} }; } diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 0307cfd6c..5552c66b6 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -30,8 +32,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include + #include "crypto/randomx/jit_compiler_x86.hpp" #include "backend/cpu/Cpu.h" +#include "crypto/common/VirtualMemory.h" #include "crypto/randomx/jit_compiler_x86_static.hpp" #include "crypto/randomx/program.hpp" #include "crypto/randomx/reciprocal.h" @@ -170,16 +174,28 @@ namespace randomx { return codePos < prologueSize ? 0 : codePos - prologueSize; } - static inline void cpuid(uint32_t level, int32_t output[4]) - { - memset(output, 0, sizeof(int32_t) * 4); + void JitCompilerX86::enableAll() { + xmrig::VirtualMemory::protectRWX(code, CodeSize); + } -# ifdef _MSC_VER - __cpuid(output, static_cast(level)); -# else - __cpuid_count(level, 0, output[0], output[1], output[2], output[3]); -# endif - } + void JitCompilerX86::enableWriting() { + xmrig::VirtualMemory::protectRW(code, CodeSize); + } + + void JitCompilerX86::enableExecution() { + xmrig::VirtualMemory::protectRX(code, CodeSize); + } + + static inline void cpuid(uint32_t level, int32_t output[4]) + { + memset(output, 0, sizeof(int32_t) * 4); + +# ifdef _MSC_VER + __cpuid(output, static_cast(level)); +# else + __cpuid_count(level, 0, output[0], output[1], output[2], output[3]); +# endif + } # ifdef _MSC_VER static FORCE_INLINE uint32_t rotl32(uint32_t a, int shift) { return _rotl(a, shift); } diff --git a/src/crypto/randomx/jit_compiler_x86.hpp b/src/crypto/randomx/jit_compiler_x86.hpp index cc535a0bc..730779239 100644 --- a/src/crypto/randomx/jit_compiler_x86.hpp +++ b/src/crypto/randomx/jit_compiler_x86.hpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -65,6 +67,9 @@ namespace randomx { return code; } size_t getCodeSize(); + void enableWriting(); + void enableExecution(); + void enableAll(); alignas(64) static InstructionGeneratorX86 engine[256]; diff --git a/src/crypto/randomx/vm_compiled.cpp b/src/crypto/randomx/vm_compiled.cpp index c40247d92..c158324d1 100644 --- a/src/crypto/randomx/vm_compiled.cpp +++ b/src/crypto/randomx/vm_compiled.cpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -47,7 +49,17 @@ namespace randomx { compiler.prepare(); VmBase::generateProgram(seed); randomx_vm::initialize(); + +# ifdef XMRIG_SECURE_JIT + compiler.enableWriting(); +# endif + compiler.generateProgram(program, config, randomx_vm::getFlags()); + +# ifdef XMRIG_SECURE_JIT + compiler.enableExecution(); +# endif + mem.memory = datasetPtr->memory + datasetOffset; execute(); } diff --git a/src/crypto/randomx/vm_compiled_light.cpp b/src/crypto/randomx/vm_compiled_light.cpp index 12e8de0f9..2adb8c72b 100644 --- a/src/crypto/randomx/vm_compiled_light.cpp +++ b/src/crypto/randomx/vm_compiled_light.cpp @@ -1,5 +1,7 @@ /* -Copyright (c) 2018-2019, tevador +Copyright (c) 2018-2020, tevador +Copyright (c) 2019-2020, SChernykh +Copyright (c) 2019-2020, XMRig , All rights reserved. @@ -36,14 +38,33 @@ namespace randomx { void CompiledLightVm::setCache(randomx_cache* cache) { cachePtr = cache; mem.memory = cache->memory; + +# ifdef XMRIG_SECURE_JIT + compiler.enableWriting(); +# endif + compiler.generateSuperscalarHash(cache->programs); + +# ifdef XMRIG_SECURE_JIT + compiler.enableExecution(); +# endif } template void CompiledLightVm::run(void* seed) { VmBase::generateProgram(seed); randomx_vm::initialize(); + +# ifdef XMRIG_SECURE_JIT + compiler.enableWriting(); +# endif + compiler.generateProgramLight(program, config, datasetOffset); + +# ifdef XMRIG_SECURE_JIT + compiler.enableExecution(); +# endif + CompiledVm::execute(); }