Skip to content

Commit

Permalink
Rewrite syscalls
Browse files Browse the repository at this point in the history
  • Loading branch information
djphoenix committed May 26, 2019
1 parent 78d67ac commit 31e3f3c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 68 deletions.
71 changes: 28 additions & 43 deletions src/platform/syscall.cpp
Expand Up @@ -69,83 +69,68 @@ 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;"
"pop %r14;"
"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);
Expand Down
3 changes: 2 additions & 1 deletion src/process/include/process.hpp
Expand Up @@ -28,7 +28,8 @@ class Process {
List<ProcessSymbol> 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:
Expand Down
52 changes: 28 additions & 24 deletions src/process/process.cpp
Expand Up @@ -8,13 +8,15 @@

using PTE = Pagetable::Entry;

Process::Process() {
id = size_t(-1);
pagetable = nullptr;
entry = 0;
_aslrCode = RAND::get<uintptr_t>(0x80000000llu, 0x100000000llu) << 12;
_aslrStack = RAND::get<uintptr_t>(0x40000000llu, 0x80000000llu) << 12;
Process::Process() :
id(uint64_t(-1)), entry(0),
_aslrCode(RAND::get<uintptr_t>(0x80000000llu, 0x100000000llu) << 12),
_aslrStack(RAND::get<uintptr_t>(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) {
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 31e3f3c

Please sign in to comment.