From 5115df07c20d963527d9e9ea45489c0377c5e297 Mon Sep 17 00:00:00 2001 From: Jia Zhang Date: Thu, 25 Jun 2020 00:30:05 +0800 Subject: [PATCH] rune/libenclave: Fix processing LD_LIBRARY_PATH #2 Instead of inheriting LD_LIBRARY_PATH by bootstrap, make it available only for boostrap's child process. Signed-off-by: Jia Zhang --- rune/libcontainer/container_linux.go | 14 +++++--------- rune/libcontainer/nsenter/loader.c | 21 ++++++++++++++++----- rune/libcontainer/nsenter/nsexec.c | 21 ++++++++++++++++----- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/rune/libcontainer/container_linux.go b/rune/libcontainer/container_linux.go index 0cffe77..66dd1c4 100644 --- a/rune/libcontainer/container_linux.go +++ b/rune/libcontainer/container_linux.go @@ -531,16 +531,12 @@ func (c *linuxContainer) commandTemplate(p *Process, childInitPipe *os.File, chi fmt.Sprintf("_LIBCONTAINER_AGENTPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1)) } + if c.config.Enclave.Path != "" { + cmd.Env = append(cmd.Env, "_LIBCONTAINER_PAL_PATH="+string(c.config.Enclave.Path)) + } + if c.config.Enclave.Signer != "server" { - rootfs := c.config.Rootfs - // LD_LIBRARY_PATH must be set before the process starts to be valid - cmd.Env = append(cmd.Env, - fmt.Sprintf("LD_LIBRARY_PATH=%s/usr/lib:%s/usr/lib64:%s/lib:%s/lib64", - rootfs, rootfs, rootfs, rootfs)); - cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_PAL_PATH=%s/%s", rootfs, c.config.Enclave.Path)) - } else if c.config.Enclave.Path != "" { - cmd.Env = append(cmd.Env, "_LIBCONTAINER_PAL_PATH=" + c.config.Enclave.Path) + cmd.Env = append(cmd.Env, "_LIBCONTAINER_PAL_ROOTFS="+string(c.config.Rootfs)) } if detached { diff --git a/rune/libcontainer/nsenter/loader.c b/rune/libcontainer/nsenter/loader.c index c7904f2..30b9bc7 100644 --- a/rune/libcontainer/nsenter/loader.c +++ b/rune/libcontainer/nsenter/loader.c @@ -4,6 +4,7 @@ #include #include #include +#include /* Defined in nsexec.c. */ @@ -37,18 +38,28 @@ int is_enclave(void) int load_enclave_runtime(void) { - const char *file; + char pal_full_path[PATH_MAX+1]; + char *pal_path; + const char *rootfs; void *dl; - file = getenv("_LIBCONTAINER_PAL_PATH"); - if (file == NULL || *file == '\0') { + pal_path = getenv("_LIBCONTAINER_PAL_PATH"); + if (pal_path == NULL || *pal_path == '\0') { write_log(DEBUG, "invalid environment _LIBCONTAINER_PAL_PATH"); return 0; } - write_log(DEBUG, "_LIBCONTAINER_PAL_PATH = %s", file); + + write_log(DEBUG, "_LIBCONTAINER_PAL_PATH = %s", pal_path); write_log(DEBUG, "LD_LIBRARY_PATH = %s", getenv("LD_LIBRARY_PATH")); - dl = dlopen(file, RTLD_NOW); + rootfs = getenv("_LIBCONTAINER_PAL_ROOTFS"); + if (rootfs && *rootfs != '\0') { + snprintf(pal_full_path, sizeof(pal_full_path) - 1, "%s/%s", rootfs, pal_path); + pal_path = pal_full_path; + } + + dl = dlopen(pal_path, RTLD_NOW); + unsetenv("LD_LIBRARY_PATH"); if (dl == NULL) { write_log(DEBUG, "dlopen(): %s", dlerror()); /* set errno correctly, make bail() work better */ diff --git a/rune/libcontainer/nsenter/nsexec.c b/rune/libcontainer/nsenter/nsexec.c index f86610c..62788a2 100644 --- a/rune/libcontainer/nsenter/nsexec.c +++ b/rune/libcontainer/nsenter/nsexec.c @@ -579,6 +579,7 @@ void nsexec(void) jmp_buf env; int sync_child_pipe[2], sync_grandchild_pipe[2]; struct nlconfig_t config = { 0 }; + char *rootfs; /* * Setup a pipe to send logs to the parent. This should happen @@ -643,6 +644,16 @@ void nsexec(void) /* TODO: Currently we aren't dealing with child deaths properly. */ + rootfs = getenv("_LIBCONTAINER_PAL_ROOTFS"); + if (rootfs && *rootfs != '\0') { + char ld_path[PATH_MAX+1]; + + snprintf(ld_path, sizeof(ld_path) - 1, + "%s/usr/lib/x86_64-linux-gnu:%s/usr/lib:%s/usr/lib64:%s/lib:%s/lib64", + rootfs, rootfs, rootfs, rootfs, rootfs); + setenv("LD_LIBRARY_PATH", ld_path, 1); + } + /* * Okay, so this is quite annoying. * @@ -702,15 +713,10 @@ void nsexec(void) int len; pid_t child, first_child = -1; bool ready = false; - int ret; /* For debugging. */ prctl(PR_SET_NAME, (unsigned long)"runc:[0:PARENT]", 0, 0, 0); - ret = load_enclave_runtime(); - if (ret < 0) - bail("load_enclave_runtime() failed, ret = %d", ret); - /* Start the process of getting a container. */ child = clone_parent(&env, JUMP_CHILD); if (child < 0) @@ -837,6 +843,11 @@ void nsexec(void) case JUMP_CHILD:{ pid_t child; enum sync_t s; + int ret; + + ret = load_enclave_runtime(); + if (ret < 0) + bail("load_enclave_runtime() failed, ret = %d", ret); /* We're in a child and thus need to tell the parent if we die. */ syncfd = sync_child_pipe[0]; -- GitLab