From 037185ff64598a0e9b75810577060b581175d9f6 Mon Sep 17 00:00:00 2001 From: Tianjia Zhang Date: Wed, 24 Jun 2020 15:11:46 +0800 Subject: [PATCH] rune/libenclave: Support Enclave Runtime PAL API v2 Signed-off-by: jack.wxz Signed-off-by: Tianjia Zhang --- rune/libcontainer/nsenter/loader.c | 20 ++- rune/libcontainer/nsenter/loader.go | 25 ++-- .../pal/{api_linux.go => api_linux_v1.go} | 6 +- .../internal/runtime/pal/api_linux_v2.go | 117 ++++++++++++++++++ .../internal/runtime/pal/pal_linux.go | 11 +- 5 files changed, 152 insertions(+), 27 deletions(-) rename rune/libenclave/internal/runtime/pal/{api_linux.go => api_linux_v1.go} (98%) create mode 100644 rune/libenclave/internal/runtime/pal/api_linux_v2.go diff --git a/rune/libcontainer/nsenter/loader.c b/rune/libcontainer/nsenter/loader.c index 33caac1..950d2f0 100644 --- a/rune/libcontainer/nsenter/loader.c +++ b/rune/libcontainer/nsenter/loader.c @@ -28,13 +28,20 @@ struct pal_stdio_fds { int stdin, stdout, stderr; }; +struct pal_create_process_args { + const char *path; + const char **argv; + const char **env; + const struct occlum_stdio_fds *stdio; + int *pid; +}; -int (*fptr_pal_get_version)(void); -int (*fptr_pal_init)(const struct pal_attr_t *attr); -int (*fptr_pal_exec)(const char *path, const char * const argv[], - const struct pal_stdio_fds *stdio, int *exit_code); -int (*fptr_pal_kill)(int sig, int pid); -int (*fptr_pal_destroy)(void); +void *fptr_pal_get_version; +void *fptr_pal_init; +void *fptr_pal_exec; +void *fptr_pal_kill; +void *fptr_pal_destroy; +void *fptr_pal_create_process; int is_enclave(void) { @@ -106,6 +113,7 @@ int load_enclave_runtime(void) DLSYM(exec); DLSYM(kill); DLSYM(destroy); + DLSYM(create_process); #undef DLSYM return 0; diff --git a/rune/libcontainer/nsenter/loader.go b/rune/libcontainer/nsenter/loader.go index 6d3c2ca..da83c00 100644 --- a/rune/libcontainer/nsenter/loader.go +++ b/rune/libcontainer/nsenter/loader.go @@ -8,21 +8,12 @@ package nsenter #include #include -struct pal_attr_t { - const char *args; - const char *log_level; -}; - -struct pal_stdio_fds { - int stdin, stdout, stderr; -}; - -extern int (*fptr_pal_get_version)(void); -extern int (*fptr_pal_init)(const struct pal_attr_t *attr); -extern int (*fptr_pal_exec)(const char *path, const char * const argv[], - const struct pal_stdio_fds *stdio, int *exit_code); -extern int (*fptr_pal_kill)(int sig, int pid); -extern int (*fptr_pal_destroy)(void); +extern void *fptr_pal_get_version; +extern void *fptr_pal_init; +extern void *fptr_pal_exec; +extern void *fptr_pal_kill; +extern void *fptr_pal_destroy; +extern void *fptr_pal_create_process; */ import "C" @@ -49,3 +40,7 @@ func SymAddrPalKill() unsafe.Pointer { func SymAddrPalDestroy() unsafe.Pointer { return unsafe.Pointer(C.fptr_pal_destroy) } + +func SymAddrPalCreateProcess() unsafe.Pointer { + return unsafe.Pointer(C.fptr_pal_create_process) +} diff --git a/rune/libenclave/internal/runtime/pal/api_linux.go b/rune/libenclave/internal/runtime/pal/api_linux_v1.go similarity index 98% rename from rune/libenclave/internal/runtime/pal/api_linux.go rename to rune/libenclave/internal/runtime/pal/api_linux_v1.go index aaf6ccb..c844ccd 100644 --- a/rune/libenclave/internal/runtime/pal/api_linux.go +++ b/rune/libenclave/internal/runtime/pal/api_linux_v1.go @@ -59,10 +59,6 @@ import ( "github.com/opencontainers/runc/libcontainer/nsenter" ) -const ( - palApiVersion = 1 -) - type enclaveRuntimePalApiV1 struct { } @@ -72,7 +68,7 @@ func (pal *enclaveRuntimePalApiV1) get_version() uint32 { if sym != nil { return uint32(C.palGetVersion(sym)) } else { - return palApiVersion + return 1 } } diff --git a/rune/libenclave/internal/runtime/pal/api_linux_v2.go b/rune/libenclave/internal/runtime/pal/api_linux_v2.go new file mode 100644 index 0000000..5244116 --- /dev/null +++ b/rune/libenclave/internal/runtime/pal/api_linux_v2.go @@ -0,0 +1,117 @@ +package enclave_runtime_pal // import "github.com/opencontainers/runc/libenclave/internal/runtime/pal" + +/* +#include + +static int palCreateProcessV2(void *sym, const char *exe, const char *argv[], + const char *envp[], int stdin, int stdout, + int stderr, int *pid) +{ + typedef struct { + int stdin, stdout, stderr; + } pal_stdio_fds; + + typedef struct { + const char *path; + const char **argv; + const char **env; + pal_stdio_fds *fds; + int *pid; + } pal_create_process_args; + + pal_stdio_fds fds = { + stdin, stdout, stderr, + }; + + pal_create_process_args create_process_args = { + exe, + argv, + envp, + &fds, + pid, + }; + + return ((int (*)(pal_create_process_args *))sym) + (&create_process_args); +} + +static int palExecV2(void *sym, int pid, int *exit_code) +{ + typedef struct { + int pid; + int *exit_value; + } pal_exec_args; + + pal_exec_args args = { + pid, + exit_code, + }; + + return ((int (*)(pal_exec_args *))sym) + (&args); +} +*/ +import "C" + +import ( + "fmt" + "github.com/sirupsen/logrus" + "os" + "strings" + "unsafe" + + "github.com/opencontainers/runc/libcontainer/nsenter" +) + +type enclaveRuntimePalApiV2 struct { +} + +func (pal *enclaveRuntimePalApiV2) exec(cmd []string, envs []string, stdio [3]*os.File) (int32, error) { + logrus.Debugf("pal exec() called with args %s", strings.Join(cmd, " ")) + + // Skip cmd[0] as used as the executable. + var exe *C.char + argc := len(cmd) + 1 + pargs := make([]*C.char, argc) + if argc > 1 { + exe = C.CString(cmd[0]) + defer C.free(unsafe.Pointer(exe)) + + for i, arg := range cmd { + logrus.Debugf("arg[%d]: %s", i, arg) + pargs[i] = C.CString(arg) + defer C.free(unsafe.Pointer(pargs[i])) + } + } + var argv **C.char = (**C.char)(unsafe.Pointer(&pargs[0])) + + envc := len(envs) + 1 + penvs := make([]*C.char, envc) + if envc > 1 { + for i, e := range envs { + logrus.Debugf("env[%d]: %s", i, e) + penvs[i] = C.CString(e) + defer C.free(unsafe.Pointer(penvs[i])) + } + } + var envp **C.char = (**C.char)(unsafe.Pointer(&penvs[0])) + + var exitCode int32 + var pid int32 + stdin := C.int(int(stdio[0].Fd())) + stdout := C.int(int(stdio[1].Fd())) + stderr := C.int(int(stdio[2].Fd())) + sym := nsenter.SymAddrPalCreateProcess() + + ret := C.palCreateProcessV2(sym, exe, argv, envp, stdin, stdout, stderr, (*C.int)(unsafe.Pointer(&pid))) + if ret < 0 { + return exitCode, fmt.Errorf("pal create process() failed with %d", ret) + } + + sym = nsenter.SymAddrPalExec() + ret = C.palExecV2(sym, C.int(pid), (*C.int)(unsafe.Pointer(&exitCode))) + if ret < 0 { + return exitCode, fmt.Errorf("pal exec() failed with %d", ret) + } + return exitCode, nil +} diff --git a/rune/libenclave/internal/runtime/pal/pal_linux.go b/rune/libenclave/internal/runtime/pal/pal_linux.go index 8bb3a4d..88c7dd3 100644 --- a/rune/libenclave/internal/runtime/pal/pal_linux.go +++ b/rune/libenclave/internal/runtime/pal/pal_linux.go @@ -5,6 +5,10 @@ import ( "os" ) +const ( + palApiVersion = 2 +) + func (pal *enclaveRuntimePal) Load(palPath string) (err error) { if err = pal.getPalApiVersion(); err != nil { return err @@ -32,7 +36,12 @@ func (pal *enclaveRuntimePal) Attest() (err error) { } func (pal *enclaveRuntimePal) Exec(cmd []string, envp []string, stdio [3]*os.File) (int32, error) { - api := &enclaveRuntimePalApiV1{} + if pal.version == 1 { + api := &enclaveRuntimePalApiV1{} + return api.exec(cmd, envp, stdio) + } + + api := &enclaveRuntimePalApiV2{} return api.exec(cmd, envp, stdio) } -- GitLab