Unverified Commit 99c42eaa by Stéphane Graber Committed by GitHub

Merge pull request #2459 from brauner/2018-07-11/cleanup_makefile

autotool fixes, attach cleanups
parents 4017e680 ae026f55
...@@ -448,12 +448,15 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -448,12 +448,15 @@ static char *lxc_attach_getpwshell(uid_t uid)
int fd, ret; int fd, ret;
pid_t pid; pid_t pid;
int pipes[2]; int pipes[2];
char *result = NULL; FILE *pipe_f;
bool found = false;
size_t line_bufsz = 0;
char *line = NULL, *result = NULL;
/* We need to fork off a process that runs the getent program, and we /* We need to fork off a process that runs the getent program, and we
* need to capture its output, so we use a pipe for that purpose. * need to capture its output, so we use a pipe for that purpose.
*/ */
ret = pipe(pipes); ret = pipe2(pipes, O_CLOEXEC);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
...@@ -464,12 +467,45 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -464,12 +467,45 @@ static char *lxc_attach_getpwshell(uid_t uid)
return NULL; return NULL;
} }
if (pid) { if (!pid) {
int status; char uid_buf[32];
FILE *pipe_f; char *arguments[] = {
int found = 0; "getent",
size_t line_bufsz = 0; "passwd",
char *line = NULL; uid_buf,
NULL
};
close(pipes[0]);
/* We want to capture stdout. */
ret = dup2(pipes[1], STDOUT_FILENO);
close(pipes[1]);
if (ret < 0)
exit(EXIT_FAILURE);
/* Get rid of stdin/stderr, so we try to associate it with
* /dev/null.
*/
fd = open_devnull();
if (fd < 0) {
close(STDIN_FILENO);
close(STDERR_FILENO);
} else {
(void)dup3(fd, STDIN_FILENO, O_CLOEXEC);
(void)dup3(fd, STDOUT_FILENO, O_CLOEXEC);
close(fd);
}
/* Finish argument list. */
ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long)uid);
if (ret <= 0 || ret >= sizeof(uid_buf))
exit(EXIT_FAILURE);
/* Try to run getent program. */
(void)execvp("getent", arguments);
exit(EXIT_FAILURE);
}
close(pipes[1]); close(pipes[1]);
...@@ -495,23 +531,28 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -495,23 +531,28 @@ static char *lxc_attach_getpwshell(uid_t uid)
token = strtok_r(line, ":", &saveptr); token = strtok_r(line, ":", &saveptr);
if (!token) if (!token)
continue; continue;
/* next: dummy password field */ /* next: dummy password field */
token = strtok_r(NULL, ":", &saveptr); token = strtok_r(NULL, ":", &saveptr);
if (!token) if (!token)
continue; continue;
/* next: user id */ /* next: user id */
token = strtok_r(NULL, ":", &saveptr); token = strtok_r(NULL, ":", &saveptr);
value = token ? strtol(token, &endptr, 10) : 0; value = token ? strtol(token, &endptr, 10) : 0;
if (!token || !endptr || *endptr || value == LONG_MIN || value == LONG_MAX) if (!token || !endptr || *endptr || value == LONG_MIN ||
value == LONG_MAX)
continue; continue;
/* dummy sanity check: user id matches */ /* dummy sanity check: user id matches */
if ((uid_t) value != uid) if ((uid_t)value != uid)
continue; continue;
/* skip fields: gid, gecos, dir, go to next field 'shell' */ /* skip fields: gid, gecos, dir, go to next field 'shell' */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
token = strtok_r(NULL, ":", &saveptr); token = strtok_r(NULL, ":", &saveptr);
if (!token) if (!token)
break; continue;
} }
if (!token) if (!token)
continue; continue;
...@@ -523,30 +564,13 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -523,30 +564,13 @@ static char *lxc_attach_getpwshell(uid_t uid)
if (token) if (token)
continue; continue;
found = 1; found = true;
} }
free(line); free(line);
fclose(pipe_f); fclose(pipe_f);
again:
if (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
goto again;
free(result);
return NULL;
}
/* Some sanity checks. If anything even hinted at going wrong,
* we can't be sure we have a valid result, so we assume we
* don't.
*/
if (!WIFEXITED(status)) { ret = wait_for_pid(pid);
free(result); if (ret < 0) {
return NULL;
}
if (WEXITSTATUS(status) != 0) {
free(result); free(result);
return NULL; return NULL;
} }
...@@ -557,43 +581,6 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -557,43 +581,6 @@ static char *lxc_attach_getpwshell(uid_t uid)
} }
return result; return result;
} else {
char uid_buf[32];
char *arguments[] = {
"getent",
"passwd",
uid_buf,
NULL
};
close(pipes[0]);
/* We want to capture stdout. */
dup2(pipes[1], 1);
close(pipes[1]);
/* Get rid of stdin/stderr, so we try to associate it with
* /dev/null.
*/
fd = open("/dev/null", O_RDWR);
if (fd < 0) {
close(0);
close(2);
} else {
dup2(fd, 0);
dup2(fd, 2);
close(fd);
}
/* Finish argument list. */
ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long) uid);
if (ret <= 0)
exit(-1);
/* Try to run getent program. */
(void) execvp("getent", arguments);
exit(-1);
}
} }
static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid) static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid)
...@@ -656,9 +643,10 @@ static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid) ...@@ -656,9 +643,10 @@ static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid)
/* Define default options if no options are supplied by the user. */ /* Define default options if no options are supplied by the user. */
static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_DEFAULT; static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_DEFAULT;
static bool fetch_seccomp(struct lxc_container *c, static bool fetch_seccomp(struct lxc_container *c, lxc_attach_options_t *options)
lxc_attach_options_t *options)
{ {
int ret;
bool bret;
char *path; char *path;
if (!(options->namespaces & CLONE_NEWNS) || if (!(options->namespaces & CLONE_NEWNS) ||
...@@ -669,62 +657,61 @@ static bool fetch_seccomp(struct lxc_container *c, ...@@ -669,62 +657,61 @@ static bool fetch_seccomp(struct lxc_container *c,
} }
/* Remove current setting. */ /* Remove current setting. */
if (!c->set_config_item(c, "lxc.seccomp", "") && if (!c->set_config_item(c, "lxc.seccomp.profile", "") &&
!c->set_config_item(c, "lxc.seccomp.profile", "")) { !c->set_config_item(c, "lxc.seccomp", "")) {
return false; return false;
} }
/* Fetch the current profile path over the cmd interface. */ /* Fetch the current profile path over the cmd interface. */
path = c->get_running_config_item(c, "lxc.seccomp.profile"); path = c->get_running_config_item(c, "lxc.seccomp.profile");
if (!path) { if (!path) {
INFO("Failed to get running config item for lxc.seccomp.profile"); INFO("Failed to retrieve lxc.seccomp.profile");
path = c->get_running_config_item(c, "lxc.seccomp"); path = c->get_running_config_item(c, "lxc.seccomp");
}
if (!path) { if (!path) {
INFO("Failed to get running config item for lxc.seccomp"); INFO("Failed to retrieve lxc.seccomp");
return true; return true;
} }
}
/* Copy the value into the new lxc_conf. */ /* Copy the value into the new lxc_conf. */
if (!c->set_config_item(c, "lxc.seccomp.profile", path)) { bret = c->set_config_item(c, "lxc.seccomp.profile", path);
free(path); free(path);
if (!bret)
return false; return false;
}
free(path);
/* Attempt to parse the resulting config. */ /* Attempt to parse the resulting config. */
if (lxc_read_seccomp_config(c->lxc_conf) < 0) { ret = lxc_read_seccomp_config(c->lxc_conf);
ERROR("Error reading seccomp policy."); if (ret < 0) {
ERROR("Failed to retrieve seccomp policy");
return false; return false;
} }
INFO("Retrieved seccomp policy."); INFO("Retrieved seccomp policy");
return true; return true;
} }
static bool no_new_privs(struct lxc_container *c, lxc_attach_options_t *options) static bool no_new_privs(struct lxc_container *c, lxc_attach_options_t *options)
{ {
bool bret;
char *val; char *val;
/* Remove current setting. */ /* Remove current setting. */
if (!c->set_config_item(c, "lxc.no_new_privs", "")) if (!c->set_config_item(c, "lxc.no_new_privs", "")) {
INFO("Failed to unset lxc.no_new_privs");
return false; return false;
}
/* Retrieve currently active setting. */ /* Retrieve currently active setting. */
val = c->get_running_config_item(c, "lxc.no_new_privs"); val = c->get_running_config_item(c, "lxc.no_new_privs");
if (!val) { if (!val) {
INFO("Failed to get running config item for lxc.no_new_privs."); INFO("Failed to retrieve lxc.no_new_privs");
return false; return false;
} }
/* Set currently active setting. */ /* Set currently active setting. */
if (!c->set_config_item(c, "lxc.no_new_privs", val)) { bret = c->set_config_item(c, "lxc.no_new_privs", val);
free(val);
return false;
}
free(val); free(val);
return bret;
return true;
} }
static signed long get_personality(const char *name, const char *lxcpath) static signed long get_personality(const char *name, const char *lxcpath)
...@@ -943,16 +930,7 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -943,16 +930,7 @@ static int attach_child_main(struct attach_clone_payload *payload)
* here, ignore errors. * here, ignore errors.
*/ */
for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) { for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
int flags; ret = fd_cloexec(fd, false);
flags = fcntl(fd, F_GETFL);
if (flags < 0)
continue;
if ((flags & FD_CLOEXEC) == 0)
continue;
ret = fcntl(fd, F_SETFL, flags & ~FD_CLOEXEC);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to clear FD_CLOEXEC from file descriptor %d", fd); SYSERROR("Failed to clear FD_CLOEXEC from file descriptor %d", fd);
goto on_error; goto on_error;
...@@ -1086,7 +1064,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1086,7 +1064,7 @@ int lxc_attach(const char *name, const char *lxcpath,
init_pid = lxc_cmd_get_init_pid(name, lxcpath); init_pid = lxc_cmd_get_init_pid(name, lxcpath);
if (init_pid < 0) { if (init_pid < 0) {
ERROR("Failed to get init pid."); ERROR("Failed to get init pid");
return -1; return -1;
} }
...@@ -1120,10 +1098,10 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1120,10 +1098,10 @@ int lxc_attach(const char *name, const char *lxcpath,
conf = init_ctx->container->lxc_conf; conf = init_ctx->container->lxc_conf;
if (!fetch_seccomp(init_ctx->container, options)) if (!fetch_seccomp(init_ctx->container, options))
WARN("Failed to get seccomp policy."); WARN("Failed to get seccomp policy");
if (!no_new_privs(init_ctx->container, options)) if (!no_new_privs(init_ctx->container, options))
WARN("Could not determine whether PR_SET_NO_NEW_PRIVS is set."); WARN("Could not determine whether PR_SET_NO_NEW_PRIVS is set");
cwd = getcwd(NULL, 0); cwd = getcwd(NULL, 0);
...@@ -1239,7 +1217,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1239,7 +1217,7 @@ int lxc_attach(const char *name, const char *lxcpath,
*/ */
ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
if (ret < 0) { if (ret < 0) {
SYSERROR("Could not set up required IPC mechanism for attaching."); SYSERROR("Could not set up required IPC mechanism for attaching");
free(cwd); free(cwd);
lxc_proc_put_context_info(init_ctx); lxc_proc_put_context_info(init_ctx);
return -1; return -1;
...@@ -1254,7 +1232,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1254,7 +1232,7 @@ int lxc_attach(const char *name, const char *lxcpath,
*/ */
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
SYSERROR("Failed to create first subprocess."); SYSERROR("Failed to create first subprocess");
free(cwd); free(cwd);
lxc_proc_put_context_info(init_ctx); lxc_proc_put_context_info(init_ctx);
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment