From 31e3f3cb7f0283e0c726c1a949896261828bb404 Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Sun, 26 May 2019 22:14:13 +0300 Subject: [PATCH] Rewrite syscalls --- src/platform/syscall.cpp | 71 +++++++++++++-------------------- src/process/include/process.hpp | 3 +- src/process/process.cpp | 52 +++++++++++++----------- 3 files changed, 58 insertions(+), 68 deletions(-) diff --git a/src/platform/syscall.cpp b/src/platform/syscall.cpp index 507d54b..6ed22c2 100644 --- a/src/platform/syscall.cpp +++ b/src/platform/syscall.cpp @@ -69,56 +69,51 @@ uint64_t Syscall::callByName(const char *name) { void __attribute((naked)) Syscall::wrapper() { asm volatile( // Save registers - "push %rax;" - "push %rcx;" - "push %rdx;" "push %rbx;" - "push %rbp;" - "push %rsi;" - "push %rdi;" - "push %r8;" - "push %r9;" - "push %r10;" "push %r11;" "push %r12;" "push %r13;" "push %r14;" "push %r15;" - // Save pagetable & stack - "mov %cr3, %rax; mov %rsp, %rbx; push %rax; push %rbx;" + // Save pagetable + "mov %cr3, %rbx;" // Set stack to absolute address - "sub $16, %rbx; ror $48, %rbx;" - "mov $4, %rcx;" - "1:" - "rol $9, %rbx;" - "mov %rbx, %rdx;" - "and $0x1FF, %rdx;" - "mov (%rax,%rdx,8), %rax;" - "and $~0xFFF, %rax; btr $63, %rax;" - "loop 1b;" - "rol $12, %rbx; and $0xFFF, %rbx; add %rax, %rbx; mov %rbx, %rsp;" + "mov %rsp, %r12; shr $39, %r12; and $0x1FF, %r12;" // r12 = ptx + "mov (%rbx,%r12,8), %r13; and $~0xFFF, %r13; btr $63, %r13;" // rbx = pt, r12 = pte + + "mov %rsp, %r12; shr $30, %r12; and $0x1FF, %r12;" // r12 = pdx + "mov (%r13,%r12,8), %r13; and $~0xFFF, %r13; btr $63, %r13;" // r13 = pde + + "mov %rsp, %r12; shr $21, %r12; and $0x1FF, %r12;" // r12 = pdpx + "mov (%r13,%r12,8), %r13; and $~0xFFF, %r13; btr $63, %r13;" // r13 = pdpe + + "mov %rsp, %r12; shr $12, %r12; and $0x1FF, %r12;" // r12 = pml4x + "mov (%r13,%r12,8), %r13; and $~0xFFF, %r13; btr $63, %r13;" // r13 = pml4e + + // Save stack + "mov %rsp, %r12;" + "mov %rsp, %r14; and $0xFFF, %r14; add %r14, %r13; mov %r13, %rsp;" // Set kernel pagetable - "_wrapper_mov_cr3: movabsq $0, %rax; mov %rax, %cr3;" + "_wrapper_mov_cr3: movabsq $0, %r13; mov %r13, %cr3;" // Find syscall handler - "mov 128(%rsp), %rdx;" - "lea _ZL11syscall_map(%rip), %rax;" + "lea _ZL11syscall_map(%rip), %r13;" "1:" - "cmp %rdx, (%rax);" + "cmp %rax, (%r13);" "je 1f;" - "cmpq $0, (%rax);" + "cmpq $0, (%r13);" "je 2f;" - "add $16, %rax;" + "add $16, %r13;" "jmp 1b;" - "1: mov 8(%rax), %rax; callq *%rax; jmp 3f;" - "2: ud2;" - "3:" + + "1:" + "mov %rcx, %r14; callq *8(%r13); mov %r14, %rcx;" // Restore process stack & pagetable - "pop %rcx; pop %rax; mov %rcx, %rsp; mov %rax, %cr3;" + "mov %r12, %rsp; mov %rbx, %cr3;" // Restore registers "pop %r15;" @@ -126,26 +121,16 @@ void __attribute((naked)) Syscall::wrapper() { "pop %r13;" "pop %r12;" "pop %r11;" - "pop %r10;" - "pop %r9;" - "pop %r8;" - "pop %rdi;" - "pop %rsi;" - "pop %rbp;" "pop %rbx;" - "pop %rdx;" - "pop %rcx;" - "pop %rax;" // Return to ring3 "sysretq;" + "2: ud2;" ); } void Syscall::setup() { - asm volatile( - "mov %%cr3, %%rax; mov %%rax, 2 + _wrapper_mov_cr3(%%rip)":::"%rax" - ); + asm volatile("mov %%cr3, %%rax; mov %%rax, 2 + _wrapper_mov_cr3(%%rip)":::"%rax"); wrmsr(MSR_STAR, uint64_t(0x10) << 48 | uint64_t(0x8) << 32); wrmsr(MSR_LSTAR, uintptr_t(wrapper)); wrmsr(MSR_SFMASK, MSR_SFMASK_IE); diff --git a/src/process/include/process.hpp b/src/process/include/process.hpp index 7f8db58..bc17d52 100644 --- a/src/process/include/process.hpp +++ b/src/process/include/process.hpp @@ -28,7 +28,8 @@ class Process { List symbols; uintptr_t entry; Pagetable::Entry* addPage(uintptr_t vaddr, void* paddr, uint8_t flags); - uintptr_t _aslrCode, _aslrStack; + uintptr_t _aslrCode, _aslrStack, _syscallPage; + size_t _syscallNum; void *iomap[2]; public: diff --git a/src/process/process.cpp b/src/process/process.cpp index a1c5fde..9458c2f 100644 --- a/src/process/process.cpp +++ b/src/process/process.cpp @@ -8,13 +8,15 @@ using PTE = Pagetable::Entry; -Process::Process() { - id = size_t(-1); - pagetable = nullptr; - entry = 0; - _aslrCode = RAND::get(0x80000000llu, 0x100000000llu) << 12; - _aslrStack = RAND::get(0x40000000llu, 0x80000000llu) << 12; +Process::Process() : + id(uint64_t(-1)), entry(0), + _aslrCode(RAND::get(0x80000000llu, 0x100000000llu) << 12), + _aslrStack(RAND::get(0x40000000llu, 0x80000000llu) << 12), + _syscallPage(0), _syscallNum(0), + pagetable(nullptr) { + iomap[0] = iomap[1] = nullptr; } + Process::~Process() { void *rsp; asm volatile("mov %%rsp, %q0; and $~0xFFF, %q0":"=r"(rsp)); if (pagetable != nullptr) { @@ -143,30 +145,32 @@ uintptr_t Process::getSymbolByName(const char* name) { } return 0; } +struct SyscallEntry { + const uint8_t _pre[2] = { + // movabsq ..., %rax + 0x48, 0xb8, + }; + const uint64_t syscall_id; + const uint8_t _post[3] = { + // syscallq; ret + 0x0f, 0x05, 0xc3, + }; + + explicit SyscallEntry(uint64_t idx) : syscall_id(idx) {} +} PACKED; uintptr_t Process::linkLibrary(const char* funcname) { uintptr_t ptr = getSymbolByName(funcname); if (ptr != 0) return ptr; uint64_t syscall_id; if ((syscall_id = Syscall::callByName(funcname)) != 0) { - struct { - uint8_t sbp[4]; - uint8_t pushac11[4]; - uint8_t movabs[2]; - uint64_t syscall_id; - uint8_t syscall[2]; - uint8_t popac11b[5]; - uint8_t ret; - } PACKED call = { - { 0x55, 0x48, 0x89, 0xe5 }, - { 0x50, 0x51, 0x41, 0x53 }, - { 0x48, 0xb8 }, - syscall_id, - { 0x0f, 0x05 }, - { 0x41, 0x5b, 0x59, 0x58, 0x5d }, - 0xc3 - }; - ptr = addSection(SectionTypeCode, sizeof(call)); + static const constexpr size_t countInPage = 0x1000 / sizeof(SyscallEntry); + if (_syscallPage == 0 || _syscallNum == countInPage) { + _syscallPage = addSection(SectionTypeCode, sizeof(SyscallEntry) * countInPage); + _syscallNum = 0; + } + struct SyscallEntry call(syscall_id); + ptr = _syscallPage + (_syscallNum++) * sizeof(SyscallEntry); writeData(ptr, &call, sizeof(call)); addSymbol(funcname, ptr); }