From f1444fae8bb4436aa16d3b9ea1d8a6b79ef5d1a7 Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Sun, 26 May 2019 20:26:36 +0300 Subject: [PATCH] Enable non-executable bit support in process pagetable --- src/platform/include/pagetable.hpp | 13 +++++++------ src/platform/syscall.cpp | 4 ++-- src/platform/syscall_setup.hpp | 1 + src/process/include/process.hpp | 4 ++-- src/process/process.cpp | 9 +++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/platform/include/pagetable.hpp b/src/platform/include/pagetable.hpp index b5baf1c..7e56fa9 100644 --- a/src/platform/include/pagetable.hpp +++ b/src/platform/include/pagetable.hpp @@ -22,21 +22,22 @@ class Pagetable { } PACKED; bool rsvd:1; uint8_t avl :3; - uintptr_t _ptr :52; + uintptr_t _ptr :51; + uint8_t nx :1; uintptr_t getUintPtr() { return _ptr << 12; } void *getPtr() { return reinterpret_cast(getUintPtr()); } Entry *getPTE() { return static_cast(getPtr()); } - Entry(): flags(0), rsvd(0), avl(0), _ptr(0) {} + Entry(): flags(0), rsvd(0), avl(0), _ptr(0), nx(0) {} Entry(uintptr_t ptr, uint8_t avl, uint8_t flags): - flags(flags), rsvd(0), avl(avl), _ptr(ptr >> 12) {} + flags(flags), rsvd(0), avl(avl), _ptr(ptr >> 12), nx(0) {} Entry(uintptr_t ptr, uint8_t flags): - flags(flags), rsvd(0), avl(0), _ptr(ptr >> 12) {} + flags(flags), rsvd(0), avl(0), _ptr(ptr >> 12), nx(0) {} Entry(const void *ptr, uint8_t avl, uint8_t flags): - flags(flags), rsvd(0), avl(avl), _ptr(uintptr_t(ptr) >> 12) {} + flags(flags), rsvd(0), avl(avl), _ptr(uintptr_t(ptr) >> 12), nx(0) {} Entry(const void *ptr, uint8_t flags): - flags(flags), rsvd(0), avl(0), _ptr(uintptr_t(ptr) >> 12) {} + flags(flags), rsvd(0), avl(0), _ptr(uintptr_t(ptr) >> 12), nx(0) {} static Entry* find(uintptr_t ptr, Entry *pagetable) { uint16_t ptx = (ptr >> (12 + 9 + 9 + 9)) & 0x1FF; diff --git a/src/platform/syscall.cpp b/src/platform/syscall.cpp index 7b57af1..db82424 100644 --- a/src/platform/syscall.cpp +++ b/src/platform/syscall.cpp @@ -88,7 +88,7 @@ void __attribute((naked)) Syscall::wrapper() { "mov %rbx, %rdx;" "and $0x1FF, %rdx;" "mov (%rax,%rdx,8), %rax;" - "and $~0xFFF, %rax;" + "and $~0xFFF, %rax; btr $63, %rax;" "loop 1b;" "rol $12, %rbx; and $0xFFF, %rbx; add %rax, %rbx; mov %rbx, %rsp;" @@ -141,5 +141,5 @@ void Syscall::setup() { wrmsr(MSR_STAR, uint64_t(0x10) << 48 | uint64_t(0x8) << 32); wrmsr(MSR_LSTAR, uintptr_t(wrapper)); wrmsr(MSR_SFMASK, MSR_SFMASK_IE); - wrmsr(MSR_EFER, rdmsr(MSR_EFER) | MSR_EFER_SCE); + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | MSR_EFER_SCE | MSR_EFER_NXE); } diff --git a/src/platform/syscall_setup.hpp b/src/platform/syscall_setup.hpp index 53ffd07..cb6945e 100644 --- a/src/platform/syscall_setup.hpp +++ b/src/platform/syscall_setup.hpp @@ -4,6 +4,7 @@ static const uint32_t MSR_LSTAR = 0xC0000082; static const uint32_t MSR_SFMASK = 0xC0000084; static const uint64_t MSR_SFMASK_IE = 1 << 9; static const uint64_t MSR_EFER_SCE = 1 << 0; +static const uint64_t MSR_EFER_NXE = 1 << 11; static inline void wrmsr(uint32_t msr_id, uint64_t msr_value) { asm volatile("wrmsr"::"c"(msr_id), "A"(msr_value), "d"(msr_value >> 32)); diff --git a/src/process/include/process.hpp b/src/process/include/process.hpp index 2277f0a..7f8db58 100644 --- a/src/process/include/process.hpp +++ b/src/process/include/process.hpp @@ -27,7 +27,7 @@ class Process { List threads; List symbols; uintptr_t entry; - void addPage(uintptr_t vaddr, void* paddr, uint8_t flags); + Pagetable::Entry* addPage(uintptr_t vaddr, void* paddr, uint8_t flags); uintptr_t _aslrCode, _aslrStack; void *iomap[2]; @@ -49,7 +49,7 @@ class Process { uintptr_t linkLibrary(const char* funcname); void allowIOPorts(uint16_t min, uint16_t max); - void writeData(uintptr_t address, void* src, size_t size); + void writeData(uintptr_t address, const void* src, size_t size); void readData(void* dst, uintptr_t address, size_t size) const; char* readString(uintptr_t address) const; diff --git a/src/process/process.cpp b/src/process/process.cpp index 683bcab..da1870f 100644 --- a/src/process/process.cpp +++ b/src/process/process.cpp @@ -63,7 +63,7 @@ Process::~Process() { } } -void Process::addPage(uintptr_t vaddr, void* paddr, uint8_t flags) { +PTE* Process::addPage(uintptr_t vaddr, void* paddr, uint8_t flags) { uint16_t ptx = (vaddr >> (12 + 9 + 9 + 9)) & 0x1FF; uint16_t pdx = (vaddr >> (12 + 9 + 9)) & 0x1FF; uint16_t pdpx = (vaddr >> (12 + 9)) & 0x1FF; @@ -92,6 +92,7 @@ void Process::addPage(uintptr_t vaddr, void* paddr, uint8_t flags) { PTE *pml4e = pte.getPTE(); flags |= 1; pml4e[pml4x] = PTE(paddr, flags); + return &pml4e[pml4x]; } uintptr_t Process::addSection(SectionType type, size_t size) { @@ -124,7 +125,7 @@ uintptr_t Process::addSection(SectionType type, size_t size) { flags |= 2; break; } - addPage(vaddr, Pagetable::alloc(), flags); + addPage(vaddr, Pagetable::alloc(), flags)->nx = type != SectionTypeCode; vaddr += 0x1000; } return addr; @@ -172,8 +173,8 @@ uintptr_t Process::linkLibrary(const char* funcname) { return ptr; } -void Process::writeData(uintptr_t address, void* src, size_t size) { - char *ptr = static_cast(src); +void Process::writeData(uintptr_t address, const void* src, size_t size) { + const uint8_t *ptr = static_cast(src); while (size > 0) { void *dest = getPhysicalAddress(address); size_t limit = 0x1000 - (uintptr_t(dest) & 0xFFF);