From b717842113c31159cfc063af96e98483decb911d Mon Sep 17 00:00:00 2001 From: "Tate, Hongliang Tian" Date: Tue, 1 Jan 2019 15:33:33 +0800 Subject: [PATCH] Switch user/kernel fsbase --- src/libos/Enclave_config.xml | 2 +- src/libos/include/task.h | 11 +++-- src/libos/src/process/spawn/mod.rs | 1 - src/libos/src/process/task.c | 12 +++--- src/libos/src/process/task.rs | 5 ++- src/libos/src/process/task_x86-64.S | 13 +++++- src/libos/src/syscall/syscall_entry.c | 1 - src/libos/src/syscall/syscall_entry_x86-64.S | 45 ++++++++++++++++++-- src/libos/src/vm/process_vm.rs | 1 - 9 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/libos/Enclave_config.xml b/src/libos/Enclave_config.xml index f18079c4..5f853be5 100644 --- a/src/libos/Enclave_config.xml +++ b/src/libos/Enclave_config.xml @@ -2,7 +2,7 @@ 0 0 - 0x80000 + 0x100000 0x1000000 8 1 diff --git a/src/libos/include/task.h b/src/libos/include/task.h index 833df503..182dcf60 100644 --- a/src/libos/include/task.h +++ b/src/libos/include/task.h @@ -13,10 +13,11 @@ extern "C" { // See Struct Task in process.rs struct Task { - uint64_t syscall_stack_addr; + uint64_t kernel_stack_addr; + uint64_t kernel_fsbase_addr; uint64_t user_stack_addr; + uint64_t user_fsbase_addr; uint64_t user_entry_addr; - uint64_t fs_base_addr; jmp_buf* saved_state; }; @@ -37,7 +38,11 @@ void do_exit_task(void); /* Override the field for stack guard */ #define TD_TASK_OFFSET TD_STACKGUARD_OFFSET -#define TASK_SYSCALL_STACK_OFFSET (8 * 0) +#define TASK_KERNEL_STACK_ADDR (8 * 0) +#define TASK_KERNEL_FSBASE_ADDR (8 * 1) +#define TASK_USER_STACK_ADDR (8 * 2) +#define TASK_USER_FSBASE_ADDR (8 * 3) +#define TASK_USER_ENTRY_ADDR (8 * 4) #endif /* __ASSEMBLY__ */ diff --git a/src/libos/src/process/spawn/mod.rs b/src/libos/src/process/spawn/mod.rs index 1c06b302..5dfe0c1b 100644 --- a/src/libos/src/process/spawn/mod.rs +++ b/src/libos/src/process/spawn/mod.rs @@ -85,7 +85,6 @@ fn init_task(user_entry: usize, stack_top: usize, Ok(Task { user_stack_addr: user_stack, user_entry_addr: user_entry, - fs_base_addr: 0, .. Default::default() }) } diff --git a/src/libos/src/process/task.c b/src/libos/src/process/task.c index d3e00e13..b390e9ae 100644 --- a/src/libos/src/process/task.c +++ b/src/libos/src/process/task.c @@ -1,12 +1,12 @@ #include "task.h" -extern void __run_task(uint64_t entry_point, uint64_t stack_top); +extern void __run_task(struct Task* task); extern uint64_t __get_stack_guard(void); extern void __set_stack_guard(uint64_t new_val); static uint64_t get_syscall_stack(struct Task* this_task) { -#define LARGE_ENOUGH_GAP 4096 +#define LARGE_ENOUGH_GAP (8192) char libos_stack_var = 0; uint64_t libos_stack = ((uint64_t) &libos_stack_var) - LARGE_ENOUGH_GAP; libos_stack &= ~0x0FUL; // stack must be 16-byte aligned @@ -20,17 +20,16 @@ static uint64_t get_syscall_stack(struct Task* this_task) { #define RESET_CURRENT_TASK() \ __set_stack_guard(stack_guard); - int do_run_task(struct Task* task) { jmp_buf libos_state = {0}; task->saved_state = &libos_state; - task->syscall_stack_addr = get_syscall_stack(task); + task->kernel_stack_addr = get_syscall_stack(task); SET_CURRENT_TASK(task); int second = setjmp(libos_state); if (!second) { - __run_task(task->user_entry_addr, task->user_stack_addr); + __run_task(task); } // From occlum_exit @@ -39,6 +38,7 @@ int do_run_task(struct Task* task) { } void do_exit_task(void) { - jmp_buf* jb = __get_current_task()->saved_state; + struct Task* task = __get_current_task(); + jmp_buf* jb = task->saved_state; longjmp(*jb, 1); } diff --git a/src/libos/src/process/task.rs b/src/libos/src/process/task.rs index 1c6f2557..1d3576ad 100644 --- a/src/libos/src/process/task.rs +++ b/src/libos/src/process/task.rs @@ -5,10 +5,11 @@ use std::{mem}; #[derive(Clone, Debug, Default)] #[repr(C)] pub struct Task { - pub syscall_stack_addr: usize, + pub kernel_stack_addr: usize, + pub kernel_fsbase_addr: usize, pub user_stack_addr: usize, + pub user_fsbase_addr: usize, pub user_entry_addr: usize, - pub fs_base_addr: usize, pub saved_state: usize, // struct jmpbuf* } diff --git a/src/libos/src/process/task_x86-64.S b/src/libos/src/process/task_x86-64.S index 409f09cd..00d8fb58 100644 --- a/src/libos/src/process/task_x86-64.S +++ b/src/libos/src/process/task_x86-64.S @@ -30,5 +30,14 @@ __set_stack_guard: .global __run_task .type __run_task, @function __run_task: - mov %rsi, %rsp - jmp *%rdi + // Save kernel fsbase + rdfsbase %r10 + movq %r10, TASK_KERNEL_FSBASE_ADDR(%rdi) + // Use user fsbase + movq TASK_USER_FSBASE_ADDR(%rdi), %r10 + wrfsbase %r10 + // Use user stack + movq TASK_USER_STACK_ADDR(%rdi), %rsp + // Run user code + movq TASK_USER_ENTRY_ADDR(%rdi), %r11 + jmp *%r11 diff --git a/src/libos/src/syscall/syscall_entry.c b/src/libos/src/syscall/syscall_entry.c index 5f4178b4..5dc4b0b7 100644 --- a/src/libos/src/syscall/syscall_entry.c +++ b/src/libos/src/syscall/syscall_entry.c @@ -6,7 +6,6 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) { long ret = 0; - switch (num) { case SYS_exit: { DECL_SYSCALL_ARG(int, status, arg0); diff --git a/src/libos/src/syscall/syscall_entry_x86-64.S b/src/libos/src/syscall/syscall_entry_x86-64.S index 4b5c5665..d578135d 100644 --- a/src/libos/src/syscall/syscall_entry_x86-64.S +++ b/src/libos/src/syscall/syscall_entry_x86-64.S @@ -5,13 +5,50 @@ .global __occlum_syscall .type __occlum_syscall, @function __occlum_syscall: - push %rbp + // num - %rdi + // arg0 - %rsi + // arg1 - %rdx + // arg2 - %rcx + // arg3 - %r8 + // arg4 - %r9 + // arg5 - *0x8(%rsp) + + // Given by the user, the user-space stack pointer %rsp cannot be trusted. + // So we need to check whether %rsp is within the read-write region of the + // current data domain + bndcl %rsp, %bnd0 + bndcu %rsp, %bnd0 + + // Save the user stack + pushq %rbp movq %rsp, %rbp - movq %gs:(TD_TASK_OFFSET), %rax - movq TASK_SYSCALL_STACK_OFFSET(%rax), %rsp + // Get current task + movq %gs:(TD_TASK_OFFSET), %r12 + // Switch to the kernel stack + movq TASK_KERNEL_STACK_ADDR(%r12), %rsp + // Use kernel fsbase + movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11 + wrfsbase %r11 + + // TODO: Pass arg5 + // pushq 0x10(%rbp) + call dispatch_syscall + // addq 0x08, %rsp + + // Use user fsbase + movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11 + wrfsbase %r11 + + // Restore the user stack movq %rbp, %rsp popq %rbp - ret + + // Check return target is a valid instruction (i.e., a cfi_label) + popq %r10 + movq (%r10), %r11 + bndcl %r11, %bnd2 + bndcu %r11, %bnd2 + jmpq *%r10 diff --git a/src/libos/src/vm/process_vm.rs b/src/libos/src/vm/process_vm.rs index 8e7bf7ce..3ebd3dda 100644 --- a/src/libos/src/vm/process_vm.rs +++ b/src/libos/src/vm/process_vm.rs @@ -8,7 +8,6 @@ lazy_static! { unsafe { vm_get_prealloced_data_space(&mut addr, &mut size) }; (addr, size) }; - println!("addr = {:X?}, size = {}", addr, size); let vm_space = unsafe { match VMSpace::new(addr, size, VMGuardAreaType::None) { Ok(vm_space) => vm_space,