int sl_fcall_mngr_clone(struct sl_fcall_mngr* mngr, struct sl_fcall_mngr* untrusted) { PANIC_ON(!sgx_is_outside_enclave(untrusted, sizeof(*untrusted))); sgx_lfence(); BUG_ON(mngr == NULL); BUG_ON(untrusted == NULL); sl_fcall_type_t type_u = untrusted->fmn_type; PANIC_ON((type_u != SL_FCALL_TYPE_ECALL) && (type_u != SL_FCALL_TYPE_OCALL)); mngr->fmn_type = type_u; int ret = sl_siglines_clone(&mngr->fmn_siglns, &untrusted->fmn_siglns, can_type_process(type_u) ? process_fcall : NULL); if (ret) return ret; //check that we have right call managers. //i.e ecall manager on untrusted or ocall manager on trusted side PANIC_ON(fcall_type2direction(type_u) != sl_siglines_get_direction(&mngr->fmn_siglns)); uint32_t num_lines = sl_siglines_size(&mngr->fmn_siglns); BUG_ON(untrusted->fmn_bufs == NULL); struct sl_fcall_buf** bufs_u = untrusted->fmn_bufs; PANIC_ON(!sgx_is_outside_enclave(bufs_u, sizeof(bufs_u[0]) * num_lines)); sgx_lfence(); mngr->fmn_bufs = bufs_u; mngr->fmn_call_table = NULL; return 0; }
int sl_siglines_clone(struct sl_siglines* sglns, struct sl_siglines* untrusted, sl_sighandler_t handler) { PANIC_ON(!sgx_is_outside_enclave(untrusted, sizeof(*untrusted))); sgx_lfence(); sl_siglines_dir_t dir = untrusted->dir; PANIC_ON((dir != SL_SIGLINES_DIR_T2U) && (dir != SL_SIGLINES_DIR_U2T)); BUG_ON(sglns == NULL); sglns->dir = dir; BUG_ON(is_direction_sender(dir) && (handler != NULL)); uint32_t num_lines = untrusted->num_lines; if ((num_lines <= 0) || ((num_lines % NBITS_PER_UINT64) != 0)) return -EINVAL; sglns->num_lines = num_lines; uint32_t nlong = num_lines / NBITS_PER_UINT64; BUG_ON(untrusted->event_lines == NULL); uint64_t* event_lines_u = untrusted->event_lines; PANIC_ON(!sgx_is_outside_enclave(event_lines_u, sizeof(uint64_t) * nlong)); sgx_lfence(); sglns->event_lines = event_lines_u; uint64_t* free_lines = NULL; if (is_direction_sender(dir)) { free_lines = malloc(sizeof(uint64_t) * nlong); if (free_lines == NULL) return -ENOMEM; for (uint32_t i = 0; i < nlong; i++) free_lines[i] = (uint64_t)(-1);// 1's -> free } sglns->free_lines = free_lines; sglns->handler = handler; return 0; }
int create_task(task_func program, size_t stack_size, struct task_info **task) { PANIC_ON(program == NULL, "Program pointer cannot be NULL"); PANIC_ON(stack_size == 0, "Cannot create task with stack size of 0."); *task = malloc(sizeof(struct task_info)); if(!*task) return -1; uint8_t *stack = (uint8_t*)malloc(stack_size); uint8_t *stack_base = stack + stack_size; if(!stack) { free(*task); return -1; } memory_zero(stack, stack_size); (*task)->stack_ptr = stack; (*task)->stack_base = stack + stack_size; (*task)->current_sp = stack + stack_size; (*task)->program = program; stack_push(*task, 514); // EFLAGS (No idea what to put here, I inspected EFLAGS at some random location and found it had the value 514) stack_push(*task, 0x08); // code segment stack_push(*task, (uint32_t)program); // EIP stack_push(*task, 0x0); // edi stack_push(*task, 0x0); // esi stack_push(*task, 0x0); // ebx stack_push(*task, 0x0); // edx stack_push(*task, 0x0); // ecx stack_push(*task, 0x0); // eax char buf[92]; uint32_t *ebp = (uint32_t*)(*task)->stack_base; uint32_t *esp = (uint32_t*)(*task)->current_sp; snprintf(buf, 92, "DEBUG: created new task with EBP: %d, ESP: %d\n", 2, ebp, esp); print(buf); return 0; }
/* Override the weak symbol defined in tRTS */ sgx_status_t do_init_switchless(struct sl_uswitchless* handle) { PANIC_ON(!sgx_is_outside_enclave(handle, sizeof(*handle))); sgx_lfence(); if (lock_cmpxchg64((uint64_t*)&sl_uswitchless_handle, (uint64_t)NULL, (uint64_t)handle) != (uint64_t)NULL) { return SGX_ERROR_UNEXPECTED; } return SGX_SUCCESS; }