attach: non-functional changes

parent ea0eb48b
...@@ -22,22 +22,24 @@ ...@@ -22,22 +22,24 @@
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <sys/mount.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/mount.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <linux/unistd.h>
#include <pwd.h> #include <lxc/lxccontainer.h>
#ifndef HAVE_DECL_PR_CAPBSET_DROP #ifndef HAVE_DECL_PR_CAPBSET_DROP
#define PR_CAPBSET_DROP 24 #define PR_CAPBSET_DROP 24
...@@ -51,28 +53,27 @@ ...@@ -51,28 +53,27 @@
#define PR_GET_NO_NEW_PRIVS 39 #define PR_GET_NO_NEW_PRIVS 39
#endif #endif
#include "namespace.h"
#include "log.h"
#include "af_unix.h" #include "af_unix.h"
#include "attach.h" #include "attach.h"
#include "caps.h" #include "caps.h"
#include "config.h"
#include "utils.h"
#include "commands.h"
#include "cgroup.h" #include "cgroup.h"
#include "lxclock.h" #include "commands.h"
#include "conf.h" #include "conf.h"
#include "lxcseccomp.h" #include "config.h"
#include <lxc/lxccontainer.h>
#include "lsm/lsm.h"
#include "confile.h" #include "confile.h"
#include "log.h"
#include "lsm/lsm.h"
#include "lxclock.h"
#include "lxcseccomp.h"
#include "namespace.h"
#include "utils.h"
#if HAVE_SYS_PERSONALITY_H #if HAVE_SYS_PERSONALITY_H
#include <sys/personality.h> #include <sys/personality.h>
#endif #endif
#ifndef SOCK_CLOEXEC #ifndef SOCK_CLOEXEC
# define SOCK_CLOEXEC 02000000 #define SOCK_CLOEXEC 02000000
#endif #endif
#ifndef MS_REC #ifndef MS_REC
...@@ -80,7 +81,7 @@ ...@@ -80,7 +81,7 @@
#endif #endif
#ifndef MS_SLAVE #ifndef MS_SLAVE
#define MS_SLAVE (1<<19) #define MS_SLAVE (1 << 19)
#endif #endif
lxc_log_define(lxc_attach, lxc); lxc_log_define(lxc_attach, lxc);
...@@ -125,7 +126,7 @@ static int lsm_openat(int procfd, pid_t pid, int on_exec) ...@@ -125,7 +126,7 @@ static int lsm_openat(int procfd, pid_t pid, int on_exec)
static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label) static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
{ {
int fret = -1; int fret = -1;
const char* name; const char *name;
char *command = NULL; char *command = NULL;
name = lsm_name(); name = lsm_name();
...@@ -143,7 +144,8 @@ static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label) ...@@ -143,7 +144,8 @@ static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
if (strcmp(name, "AppArmor") == 0) { if (strcmp(name, "AppArmor") == 0) {
int size; int size;
command = malloc(strlen(lsm_label) + strlen("changeprofile ") + 1); command =
malloc(strlen(lsm_label) + strlen("changeprofile ") + 1);
if (!command) { if (!command) {
SYSERROR("Failed to write apparmor profile."); SYSERROR("Failed to write apparmor profile.");
goto out; goto out;
...@@ -185,12 +187,12 @@ out: ...@@ -185,12 +187,12 @@ out:
#define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1) #define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
{ {
int ret;
bool found;
FILE *proc_file; FILE *proc_file;
char proc_fn[__PROC_STATUS_LEN]; char proc_fn[__PROC_STATUS_LEN];
bool found;
int ret;
char *line = NULL;
size_t line_bufsz = 0; size_t line_bufsz = 0;
char *line = NULL;
struct lxc_proc_context_info *info = NULL; struct lxc_proc_context_info *info = NULL;
/* Read capabilities. */ /* Read capabilities. */
...@@ -224,7 +226,8 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) ...@@ -224,7 +226,8 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
fclose(proc_file); fclose(proc_file);
if (!found) { if (!found) {
SYSERROR("Could not read capability bounding set from %s.", proc_fn); SYSERROR("Could not read capability bounding set from %s.",
proc_fn);
errno = ENOENT; errno = ENOENT;
goto on_error; goto on_error;
} }
...@@ -251,7 +254,6 @@ static int lxc_attach_to_ns(pid_t pid, int which) ...@@ -251,7 +254,6 @@ static int lxc_attach_to_ns(pid_t pid, int which)
int fd[LXC_NS_MAX]; int fd[LXC_NS_MAX];
int i, j, saved_errno; int i, j, saved_errno;
if (access("/proc/self/ns", X_OK)) { if (access("/proc/self/ns", X_OK)) {
ERROR("Does this kernel version support namespaces?"); ERROR("Does this kernel version support namespaces?");
return -1; return -1;
...@@ -275,7 +277,8 @@ static int lxc_attach_to_ns(pid_t pid, int which) ...@@ -275,7 +277,8 @@ static int lxc_attach_to_ns(pid_t pid, int which)
close(fd[j]); close(fd[j]);
errno = saved_errno; errno = saved_errno;
SYSERROR("Failed to open namespace: \"%s\".", ns_info[i].proc_name); SYSERROR("Failed to open namespace: \"%s\".",
ns_info[i].proc_name);
return -1; return -1;
} }
} }
...@@ -291,7 +294,8 @@ static int lxc_attach_to_ns(pid_t pid, int which) ...@@ -291,7 +294,8 @@ static int lxc_attach_to_ns(pid_t pid, int which)
close(fd[j]); close(fd[j]);
errno = saved_errno; errno = saved_errno;
SYSERROR("Failed to attach to namespace \"%s\".", ns_info[i].proc_name); SYSERROR("Failed to attach to namespace \"%s\".",
ns_info[i].proc_name);
return -1; return -1;
} }
...@@ -314,7 +318,7 @@ static int lxc_attach_remount_sys_proc(void) ...@@ -314,7 +318,7 @@ static int lxc_attach_remount_sys_proc(void)
} }
if (detect_shared_rootfs()) { if (detect_shared_rootfs()) {
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL)) {
SYSERROR("Failed to make / rslave."); SYSERROR("Failed to make / rslave.");
ERROR("Continuing..."); ERROR("Continuing...");
} }
...@@ -354,9 +358,9 @@ static int lxc_attach_remount_sys_proc(void) ...@@ -354,9 +358,9 @@ static int lxc_attach_remount_sys_proc(void)
static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx) static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
{ {
int last_cap = lxc_caps_last_cap(); int cap, last_cap;
int cap;
last_cap = lxc_caps_last_cap();
for (cap = 0; cap <= last_cap; cap++) { for (cap = 0; cap <= last_cap; cap++) {
if (ctx->capability_mask & (1LL << cap)) if (ctx->capability_mask & (1LL << cap))
continue; continue;
...@@ -370,11 +374,12 @@ static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx) ...@@ -370,11 +374,12 @@ static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
return 0; return 0;
} }
static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char** extra_env, char** extra_keep) static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy,
char **extra_env, char **extra_keep)
{ {
if (policy == LXC_ATTACH_CLEAR_ENV) { if (policy == LXC_ATTACH_CLEAR_ENV) {
char **extra_keep_store = NULL;
int path_kept = 0; int path_kept = 0;
char **extra_keep_store = NULL;
if (extra_keep) { if (extra_keep) {
size_t count, i; size_t count, i;
...@@ -410,6 +415,7 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char* ...@@ -410,6 +415,7 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char*
if (clearenv()) { if (clearenv()) {
char **p; char **p;
SYSERROR("Failed to clear environment."); SYSERROR("Failed to clear environment.");
if (extra_keep_store) { if (extra_keep_store) {
for (p = extra_keep_store; *p; p++) for (p = extra_keep_store; *p; p++)
...@@ -421,6 +427,7 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char* ...@@ -421,6 +427,7 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char*
if (extra_keep_store) { if (extra_keep_store) {
size_t i; size_t i;
for (i = 0; extra_keep[i]; i++) { for (i = 0; extra_keep[i]; i++) {
if (extra_keep_store[i]) { if (extra_keep_store[i]) {
if (setenv(extra_keep[i], extra_keep_store[i], 1) < 0) if (setenv(extra_keep[i], extra_keep_store[i], 1) < 0)
...@@ -469,10 +476,9 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char* ...@@ -469,10 +476,9 @@ static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char*
static char *lxc_attach_getpwshell(uid_t uid) static char *lxc_attach_getpwshell(uid_t uid)
{ {
int fd, ret;
pid_t pid; pid_t pid;
int pipes[2]; int pipes[2];
int ret;
int fd;
char *result = NULL; char *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
...@@ -490,21 +496,20 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -490,21 +496,20 @@ static char *lxc_attach_getpwshell(uid_t uid)
} }
if (pid) { if (pid) {
int status;
FILE *pipe_f; FILE *pipe_f;
char *line = NULL;
size_t line_bufsz = 0;
int found = 0; int found = 0;
int status; size_t line_bufsz = 0;
char *line = NULL;
close(pipes[1]); close(pipes[1]);
pipe_f = fdopen(pipes[0], "r"); pipe_f = fdopen(pipes[0], "r");
while (getline(&line, &line_bufsz, pipe_f) != -1) { while (getline(&line, &line_bufsz, pipe_f) != -1) {
char *token;
char *saveptr = NULL;
long value;
char *endptr = NULL;
int i; int i;
long value;
char *token;
char *endptr = NULL, *saveptr = NULL;
/* If we already found something, just continue to read /* If we already found something, just continue to read
* until the pipe doesn't deliver any more data, but * until the pipe doesn't deliver any more data, but
...@@ -615,7 +620,7 @@ static char *lxc_attach_getpwshell(uid_t uid) ...@@ -615,7 +620,7 @@ static char *lxc_attach_getpwshell(uid_t uid)
} }
} }
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)
{ {
FILE *proc_file; FILE *proc_file;
char proc_fn[__PROC_STATUS_LEN]; char proc_fn[__PROC_STATUS_LEN];
...@@ -639,11 +644,11 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid) ...@@ -639,11 +644,11 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
*/ */
ret = sscanf(line, "Uid: %ld", &value); ret = sscanf(line, "Uid: %ld", &value);
if (ret != EOF && ret == 1) { if (ret != EOF && ret == 1) {
uid = (uid_t) value; uid = (uid_t)value;
} else { } else {
ret = sscanf(line, "Gid: %ld", &value); ret = sscanf(line, "Gid: %ld", &value);
if (ret != EOF && ret == 1) if (ret != EOF && ret == 1)
gid = (gid_t) value; gid = (gid_t)value;
} }
if (uid != (uid_t)-1 && gid != (gid_t)-1) if (uid != (uid_t)-1 && gid != (gid_t)-1)
break; break;
...@@ -665,16 +670,21 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid) ...@@ -665,16 +670,21 @@ static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
struct attach_clone_payload { struct attach_clone_payload {
int ipc_socket; int ipc_socket;
lxc_attach_options_t* options; lxc_attach_options_t *options;
struct lxc_proc_context_info* init_ctx; struct lxc_proc_context_info *init_ctx;
lxc_attach_exec_t exec_function; lxc_attach_exec_t exec_function;
void* exec_payload; void *exec_payload;
}; };
static int attach_child_main(void* data); static int attach_child_main(void* data);
/* Help the optimizer along if it doesn't know that exit always exits. */ /* Help the optimizer along if it doesn't know that exit always exits. */
#define rexit(c) do { int __c = (c); _exit(__c); return __c; } while(0) #define rexit(c) \
do { \
int __c = (c); \
_exit(__c); \
return __c; \
} while (0)
/* 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;
...@@ -684,7 +694,8 @@ static bool fetch_seccomp(struct lxc_container *c, ...@@ -684,7 +694,8 @@ static bool fetch_seccomp(struct lxc_container *c,
{ {
char *path; char *path;
if (!(options->namespaces & CLONE_NEWNS) || !(options->attach_flags & LXC_ATTACH_LSM)) { if (!(options->namespaces & CLONE_NEWNS) ||
!(options->attach_flags & LXC_ATTACH_LSM)) {
free(c->lxc_conf->seccomp); free(c->lxc_conf->seccomp);
c->lxc_conf->seccomp = NULL; c->lxc_conf->seccomp = NULL;
return true; return true;
...@@ -724,15 +735,13 @@ static bool fetch_seccomp(struct lxc_container *c, ...@@ -724,15 +735,13 @@ static bool fetch_seccomp(struct lxc_container *c,
return true; return true;
} }
static bool no_new_privs(struct lxc_container *c, static bool no_new_privs(struct lxc_container *c, lxc_attach_options_t *options)
lxc_attach_options_t *options)
{ {
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", ""))
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");
...@@ -753,25 +762,29 @@ static bool no_new_privs(struct lxc_container *c, ...@@ -753,25 +762,29 @@ static bool no_new_privs(struct lxc_container *c,
static signed long get_personality(const char *name, const char *lxcpath) static signed long get_personality(const char *name, const char *lxcpath)
{ {
char *p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath); char *p;
signed long ret; signed long ret;
p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath);
if (!p) if (!p)
return -1; return -1;
ret = lxc_config_parse_arch(p); ret = lxc_config_parse_arch(p);
free(p); free(p);
return ret; return ret;
} }
int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process) int lxc_attach(const char *name, const char *lxcpath,
lxc_attach_exec_t exec_function, void *exec_payload,
lxc_attach_options_t *options, pid_t *attached_process)
{ {
int ret, status; int ret, status;
pid_t init_pid, pid, attached_pid, expected;
struct lxc_proc_context_info *init_ctx;
char* cwd;
char* new_cwd;
int ipc_sockets[2]; int ipc_sockets[2];
char *cwd, *new_cwd;
signed long personality; signed long personality;
pid_t attached_pid, expected, init_pid, pid;
struct lxc_proc_context_info *init_ctx;
if (!options) if (!options)
options = &attach_static_default_options; options = &attach_static_default_options;
...@@ -784,14 +797,13 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -784,14 +797,13 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
init_ctx = lxc_proc_get_context_info(init_pid); init_ctx = lxc_proc_get_context_info(init_pid);
if (!init_ctx) { if (!init_ctx) {
ERROR("Failed to get context of init process: %ld.", ERROR("Failed to get context of init process: %ld", (long)init_pid);
(long)init_pid);
return -1; return -1;
} }
personality = get_personality(name, lxcpath); personality = get_personality(name, lxcpath);
if (init_ctx->personality < 0) { if (init_ctx->personality < 0) {
ERROR("Failed to get personality of the container."); ERROR("Failed to get personality of the container");
lxc_proc_put_context_info(init_ctx); lxc_proc_put_context_info(init_ctx);
return -1; return -1;
} }
...@@ -876,7 +888,6 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -876,7 +888,6 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
* setns() (otherwise, user namespaces will hate us). * setns() (otherwise, user namespaces will hate us).
*/ */
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);
...@@ -901,9 +912,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -901,9 +912,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
} }
/* Setup resource limits */ /* Setup resource limits */
if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits) && setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid)) { if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits))
goto on_error; if (setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid) < 0)
} goto on_error;
/* Open /proc before setns() to the containers namespace so we /* Open /proc before setns() to the containers namespace so we
* don't rely on any information from inside the container. * don't rely on any information from inside the container.
...@@ -924,7 +935,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -924,7 +935,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
} }
/* Get pid of attached process from intermediate process. */ /* Get pid of attached process from intermediate process. */
ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid, sizeof(attached_pid), NULL); ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid,
sizeof(attached_pid), NULL);
if (ret <= 0) { if (ret <= 0) {
if (ret != 0) if (ret != 0)
ERROR("Expected to receive pid: %s.", strerror(errno)); ERROR("Expected to receive pid: %s.", strerror(errno));
...@@ -955,7 +967,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -955,7 +967,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
/* Wait for the attached process to finish initializing. */ /* Wait for the attached process to finish initializing. */
expected = 1; expected = 1;
ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected); ret = lxc_read_nointr_expect(ipc_sockets[0], &status,
sizeof(status), &expected);
if (ret <= 0) { if (ret <= 0) {
if (ret != 0) if (ret != 0)
ERROR("Expected to receive sequence number 1: %s.", strerror(errno)); ERROR("Expected to receive sequence number 1: %s.", strerror(errno));
...@@ -974,7 +987,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -974,7 +987,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
* up its LSM labels. * up its LSM labels.
*/ */
expected = 3; expected = 3;
ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected); ret = lxc_read_nointr_expect(ipc_sockets[0], &status,
sizeof(status), &expected);
if (ret <= 0) { if (ret <= 0) {
ERROR("Expected to receive sequence number 3: %s.", ERROR("Expected to receive sequence number 3: %s.",
strerror(errno)); strerror(errno));
...@@ -982,9 +996,12 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -982,9 +996,12 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
} }
/* Open LSM fd and send it to child. */ /* Open LSM fd and send it to child. */
if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) { if ((options->namespaces & CLONE_NEWNS) &&
(options->attach_flags & LXC_ATTACH_LSM) &&
init_ctx->lsm_label) {
int on_exec, saved_errno; int on_exec, saved_errno;
int labelfd = -1; int labelfd = -1;
on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0; on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
/* Open fd for the LSM security module. */ /* Open fd for the LSM security module. */
labelfd = lsm_openat(procfd, attached_pid, on_exec); labelfd = lsm_openat(procfd, attached_pid, on_exec);
...@@ -1025,7 +1042,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -1025,7 +1042,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
shutdown(ipc_sockets[0], SHUT_RDWR); shutdown(ipc_sockets[0], SHUT_RDWR);
close(ipc_sockets[0]); close(ipc_sockets[0]);
if (to_cleanup_pid) if (to_cleanup_pid)
(void) wait_for_pid(to_cleanup_pid); (void)wait_for_pid(to_cleanup_pid);
lxc_proc_put_context_info(init_ctx); lxc_proc_put_context_info(init_ctx);
return -1; return -1;
} }
...@@ -1038,7 +1055,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -1038,7 +1055,8 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
/* Wait for the parent to have setup cgroups. */ /* Wait for the parent to have setup cgroups. */
expected = 0; expected = 0;
status = -1; status = -1;
ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status), &expected); ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status),
&expected);
if (ret <= 0) { if (ret <= 0) {
ERROR("Expected to receive sequence number 0: %s.", strerror(errno)); ERROR("Expected to receive sequence number 0: %s.", strerror(errno));
shutdown(ipc_sockets[1], SHUT_RDWR); shutdown(ipc_sockets[1], SHUT_RDWR);
...@@ -1112,21 +1130,17 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -1112,21 +1130,17 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
static int attach_child_main(void* data) static int attach_child_main(void* data)
{ {
struct attach_clone_payload* payload = (struct attach_clone_payload*)data; int expected, fd, lsm_labelfd, ret, status;
int ipc_socket = payload->ipc_socket; long flags;
lxc_attach_options_t* options = payload->options;
struct lxc_proc_context_info* init_ctx = payload->init_ctx;
#if HAVE_SYS_PERSONALITY_H #if HAVE_SYS_PERSONALITY_H
long new_personality; long new_personality;
#endif #endif
int ret;
int status;
int expected;
long flags;
int fd;
int lsm_labelfd;
uid_t new_uid; uid_t new_uid;
gid_t new_gid; gid_t new_gid;
struct attach_clone_payload* payload = (struct attach_clone_payload*)data;
int ipc_socket = payload->ipc_socket;
lxc_attach_options_t* options = payload->options;
struct lxc_proc_context_info* init_ctx = payload->init_ctx;
/* Wait for the initial thread to signal us that it's ready for us to /* Wait for the initial thread to signal us that it's ready for us to
* start initializing. * start initializing.
...@@ -1145,7 +1159,8 @@ static int attach_child_main(void* data) ...@@ -1145,7 +1159,8 @@ static int attach_child_main(void* data)
* parent process, otherwise /proc may not properly reflect the new pid * parent process, otherwise /proc may not properly reflect the new pid
* namespace. * namespace.
*/ */
if (!(options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_REMOUNT_PROC_SYS)) { if (!(options->namespaces & CLONE_NEWNS) &&
(options->attach_flags & LXC_ATTACH_REMOUNT_PROC_SYS)) {
ret = lxc_attach_remount_sys_proc(); ret = lxc_attach_remount_sys_proc();
if (ret < 0) { if (ret < 0) {
shutdown(ipc_socket, SHUT_RDWR); shutdown(ipc_socket, SHUT_RDWR);
...@@ -1182,7 +1197,9 @@ static int attach_child_main(void* data) ...@@ -1182,7 +1197,9 @@ static int attach_child_main(void* data)
/* Always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL) /* Always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL)
* if you want this to be a no-op). * if you want this to be a no-op).
*/ */
ret = lxc_attach_set_environment(options->env_policy, options->extra_env_vars, options->extra_keep_env); ret = lxc_attach_set_environment(options->env_policy,
options->extra_env_vars,
options->extra_keep_env);
if (ret < 0) { if (ret < 0) {
ERROR("Could not set initial environment for attached process."); ERROR("Could not set initial environment for attached process.");
shutdown(ipc_socket, SHUT_RDWR); shutdown(ipc_socket, SHUT_RDWR);
...@@ -1226,7 +1243,8 @@ static int attach_child_main(void* data) ...@@ -1226,7 +1243,8 @@ static int attach_child_main(void* data)
rexit(-1); rexit(-1);
} }
} }
if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) && setuid(new_uid)) { if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) &&
setuid(new_uid)) {
SYSERROR("Switching to container uid."); SYSERROR("Switching to container uid.");
shutdown(ipc_socket, SHUT_RDWR); shutdown(ipc_socket, SHUT_RDWR);
rexit(-1); rexit(-1);
...@@ -1276,7 +1294,8 @@ static int attach_child_main(void* data) ...@@ -1276,7 +1294,8 @@ static int attach_child_main(void* data)
rexit(-1); rexit(-1);
} }
if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) { if ((options->namespaces & CLONE_NEWNS) &&
(options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
int on_exec; int on_exec;
/* Receive fd for LSM security module. */ /* Receive fd for LSM security module. */
ret = lxc_abstract_unix_recv_fds(ipc_socket, &lsm_labelfd, 1, NULL, 0); ret = lxc_abstract_unix_recv_fds(ipc_socket, &lsm_labelfd, 1, NULL, 0);
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
#ifndef __LXC_ATTACH_H #ifndef __LXC_ATTACH_H
#define __LXC_ATTACH_H #define __LXC_ATTACH_H
#include <sys/types.h>
#include <lxc/attach_options.h> #include <lxc/attach_options.h>
#include <sys/types.h>
struct lxc_conf; struct lxc_conf;
...@@ -36,6 +36,8 @@ struct lxc_proc_context_info { ...@@ -36,6 +36,8 @@ struct lxc_proc_context_info {
unsigned long long capability_mask; unsigned long long capability_mask;
}; };
extern int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process); extern int lxc_attach(const char *name, const char *lxcpath,
lxc_attach_exec_t exec_function, void *exec_payload,
lxc_attach_options_t *options, pid_t *attached_process);
#endif #endif /* __LXC_ATTACH_H */
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