From 97699bdc0d2f27c58991ef5a7aeae26bc8b2a03c Mon Sep 17 00:00:00 2001 From: Jia Zhang Date: Mon, 3 Aug 2020 14:39:41 +0800 Subject: [PATCH] rune/libenclave/skeleton: Support fork-test argument This argument is used to test whether enclave share mapping between parent and child process is usable. Signed-off-by: Jia Zhang --- .../runtime/pal/skeleton/liberpal-skeleton.c | 33 +++++++++++++++++++ .../internal/runtime/pal/skeleton/sgx_call.S | 9 +++++ 2 files changed, 42 insertions(+) diff --git a/rune/libenclave/internal/runtime/pal/skeleton/liberpal-skeleton.c b/rune/libenclave/internal/runtime/pal/skeleton/liberpal-skeleton.c index 63469e2..09cdf9c 100644 --- a/rune/libenclave/internal/runtime/pal/skeleton/liberpal-skeleton.c +++ b/rune/libenclave/internal/runtime/pal/skeleton/liberpal-skeleton.c @@ -19,6 +19,7 @@ #else #include #endif +#include #include "defines.h" #include "sgx_call.h" @@ -36,11 +37,13 @@ static bool initialized = false; static char *sgx_dev_path; static bool is_oot_driver; static bool no_sgx_flc = false; +static bool fork_test = false; /* * For SGX in-tree driver, dev_fd cannot be closed until an enclave instance * intends to exit. */ static int enclave_fd = -1; +void *tcs_busy; static bool is_sgx_device(const char *dev) { @@ -368,6 +371,8 @@ static void check_opts(const char *opt) { if (!strcmp(opt, "no-sgx-flc")) no_sgx_flc = true; + else if (!strcmp(opt, "fork-test")) + fork_test = true; } static void parse_args(const char *args) @@ -416,6 +421,12 @@ int pal_init(pal_attr_t *attr) detect_driver_type(); + tcs_busy = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (tcs_busy == MAP_FAILED) + return -EINVAL; + *(uint8_t *)tcs_busy = 0; + if (!encl_data_map(IMAGE, &bin, &bin_size)) return -ENOENT; @@ -450,6 +461,25 @@ int pal_exec(char *path, char *argv[], pal_stdio_fds *stdio, return -1; } + bool is_child = false; + + if (fork_test) { + switch (fork()) { + case -1: + fprintf(fp, "fork(), errno = %d\n", errno); + fclose(fp); + return -1; + case 0: + fprintf(fp, "run in child process, pid = %d\n", (int)getpid()); + is_child = true; + break; + default: + wait(NULL); + fprintf(fp, "run in parent process, pid = %d\n", (int)getpid()); + break; + } + } + uint64_t result = 0; int ret = SGX_ENTER_1_ARG(ECALL_MAGIC, (void *)secs.base, &result); if (ret) { @@ -466,6 +496,9 @@ int pal_exec(char *path, char *argv[], pal_stdio_fds *stdio, fprintf(fp, "Enclave runtime skeleton initialization succeeded\n"); fclose(fp); + if (fork_test && is_child) + exit(0); + *exit_code = 0; return 0; diff --git a/rune/libenclave/internal/runtime/pal/skeleton/sgx_call.S b/rune/libenclave/internal/runtime/pal/skeleton/sgx_call.S index 11627f3..4112f13 100644 --- a/rune/libenclave/internal/runtime/pal/skeleton/sgx_call.S +++ b/rune/libenclave/internal/runtime/pal/skeleton/sgx_call.S @@ -14,7 +14,12 @@ .global sgx_ecall .type sgx_ecall, @function sgx_ecall: + mov $1, %rax push %rbx + mov tcs_busy(%rip), %rbx + xchgb (%rbx), %al + cmpb $1, %al + jz busy_err push %rbp push %rdi push %rsi @@ -33,6 +38,9 @@ sgx_ecall: lea sgx_async_exit(%rip), %rcx sgx_async_exit: ENCLU + xor %rax, %rax + mov tcs_busy(%rip), %rbx + movb %al, (%rbx) # Return value is saved in RAX. mov %rdx, %rax pop %r15 @@ -42,5 +50,6 @@ sgx_async_exit: pop %rsi pop %rdi pop %rbp +busy_err: pop %rbx ret -- GitLab