diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c index 554ffd6c2ab..c2fa8aa3412 100644 --- a/libcontainer/nsenter/nsexec.c +++ b/libcontainer/nsenter/nsexec.c @@ -380,39 +380,48 @@ static int clone_parent(jmp_buf *env, int jmpval) } /* - * Gets the init pipe fd from the environment, which is used to read the - * bootstrap data and tell the parent what the new pid is after we finish - * setting up the environment. + * Returns an environment variable value as a non-negative integer, or -ENOENT + * if the variable was not found or has an empty value. + * + * If the value can not be converted to an integer, or the result is out of + * range, the function bails out. */ -static int initpipe(void) +static int getenv_int(const char *name) { - int pipenum; - char *initpipe, *endptr; + char *val, *endptr; + int ret; - initpipe = getenv("_LIBCONTAINER_INITPIPE"); - if (initpipe == NULL || *initpipe == '\0') - return -1; + val = getenv(name); + /* Treat empty value as unset variable. */ + if (val == NULL || *val == '\0') + return -ENOENT; - pipenum = strtol(initpipe, &endptr, 10); - if (*endptr != '\0') - bail("unable to parse _LIBCONTAINER_INITPIPE"); + ret = strtol(val, &endptr, 10); + if (val == endptr || *endptr != '\0') + bail("unable to parse %s=%s", name, val); + /* + * Sanity check: this must be a non-negative number. + */ + if (ret < 0) + bail("bad value for %s=%s (%d)", name, val, ret); - return pipenum; + return ret; } +/* + * Sets up logging by getting log fd from the environment, + * if available. + */ static void setup_logpipe(void) { - char *logpipe, *endptr; + int i; - logpipe = getenv("_LIBCONTAINER_LOGPIPE"); - if (logpipe == NULL || *logpipe == '\0') { + i = getenv_int("_LIBCONTAINER_LOGPIPE"); + if (i < 0) { + /* We are not runc init, or log pipe was not provided. */ return; } - - logfd = strtol(logpipe, &endptr, 10); - if (logpipe == endptr || *endptr != '\0') { - bail("unable to parse _LIBCONTAINER_LOGPIPE, value: %s", logpipe); - } + logfd = i; } /* Returns the clone(2) flag for a namespace, given the name of a namespace. */ @@ -623,12 +632,15 @@ void nsexec(void) setup_logpipe(); /* - * If we don't have an init pipe, just return to the go routine. - * We'll only get an init pipe for start or exec. + * Get the init pipe fd from the environment. The init pipe is used to + * read the bootstrap data and tell the parent what the new pids are + * after the setup is done. */ - pipenum = initpipe(); - if (pipenum == -1) + pipenum = getenv_int("_LIBCONTAINER_INITPIPE"); + if (pipenum < 0) { + /* We are not a runc init. Just return to go runtime. */ return; + } /* * We need to re-exec if we are not in a cloned binary. This is necessary