Commit 5112cd70 by Serge Hallyn

always ensure a /proc while setting up container

Otherwise we can't open /proc/self/fd to find the fds to close. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent f8744a95
...@@ -2617,7 +2617,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2617,7 +2617,7 @@ struct lxc_conf *lxc_conf_init(void)
lxc_list_init(&new->groups); lxc_list_init(&new->groups);
new->lsm_aa_profile = NULL; new->lsm_aa_profile = NULL;
new->lsm_se_context = NULL; new->lsm_se_context = NULL;
new->lsm_umount_proc = 0; new->tmp_umount_proc = 0;
for (i = 0; i < LXC_NS_MAX; i++) for (i = 0; i < LXC_NS_MAX; i++)
new->inherit_ns_fd[i] = -1; new->inherit_ns_fd[i] = -1;
...@@ -3518,6 +3518,77 @@ static int check_autodev( const char *rootfs, void *data ) ...@@ -3518,6 +3518,77 @@ static int check_autodev( const char *rootfs, void *data )
return 0; return 0;
} }
/*
* _do_tmp_proc_mount: Mount /proc inside container if not already
* mounted
*
* @rootfs : the rootfs where proc should be mounted
*
* Returns < 0 on failure, 0 if the correct proc was already mounted
* and 1 if a new proc was mounted.
*/
static int do_tmp_proc_mount(const char *rootfs)
{
char path[MAXPATHLEN];
char link[20];
int linklen, ret;
ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
if (ret < 0 || ret >= MAXPATHLEN) {
SYSERROR("proc path name too long");
return -1;
}
memset(link, 0, 20);
linklen = readlink(path, link, 20);
INFO("I am %d, /proc/self points to '%s'", getpid(), link);
ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs);
if (linklen < 0) /* /proc not mounted */
goto domount;
/* can't be longer than rootfs/proc/1 */
if (strncmp(link, "1", linklen) != 0) {
/* wrong /procs mounted */
umount2(path, MNT_DETACH); /* ignore failure */
goto domount;
}
/* the right proc is already mounted */
return 0;
domount:
if (mount("proc", path, "proc", 0, NULL))
return -1;
INFO("Mounted /proc in container for security transition");
return 1;
}
int tmp_proc_mount(struct lxc_conf *lxc_conf)
{
int mounted;
if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) {
if (mount("proc", "/proc", "proc", 0, NULL)) {
SYSERROR("Failed mounting /proc, proceeding");
mounted = 0;
} else
mounted = 1;
} else
mounted = do_tmp_proc_mount(lxc_conf->rootfs.mount);
if (mounted == -1) {
SYSERROR("failed to mount /proc in the container.");
return -1;
} else if (mounted == 1) {
lxc_conf->tmp_umount_proc = 1;
}
return 0;
}
void tmp_proc_unmount(struct lxc_conf *lxc_conf)
{
if (lxc_conf->tmp_umount_proc == 1) {
umount("/proc");
lxc_conf->tmp_umount_proc = 0;
}
}
int lxc_setup(struct lxc_handler *handler) int lxc_setup(struct lxc_handler *handler)
{ {
const char *name = handler->name; const char *name = handler->name;
...@@ -3621,8 +3692,8 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3621,8 +3692,8 @@ int lxc_setup(struct lxc_handler *handler)
return -1; return -1;
} }
/* mount /proc if needed for LSM transition */ /* mount /proc if it's not already there */
if (lsm_proc_mount(lxc_conf) < 0) { if (tmp_proc_mount(lxc_conf) < 0) {
ERROR("failed to LSM mount proc for '%s'", name); ERROR("failed to LSM mount proc for '%s'", name);
return -1; return -1;
} }
......
...@@ -301,7 +301,7 @@ struct lxc_conf { ...@@ -301,7 +301,7 @@ struct lxc_conf {
char *lsm_aa_profile; char *lsm_aa_profile;
char *lsm_se_context; char *lsm_se_context;
int lsm_umount_proc; int tmp_umount_proc;
char *seccomp; // filename with the seccomp rules char *seccomp; // filename with the seccomp rules
#if HAVE_SCMP_FILTER_CTX #if HAVE_SCMP_FILTER_CTX
scmp_filter_ctx *seccomp_ctx; scmp_filter_ctx *seccomp_ctx;
...@@ -378,4 +378,5 @@ extern int ttys_shift_ids(struct lxc_conf *c); ...@@ -378,4 +378,5 @@ extern int ttys_shift_ids(struct lxc_conf *c);
extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data); extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data);
extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
char **mntdata); char **mntdata);
extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
#endif #endif
...@@ -94,77 +94,4 @@ int lsm_process_label_set(const char *label, int use_default, int on_exec) ...@@ -94,77 +94,4 @@ int lsm_process_label_set(const char *label, int use_default, int on_exec)
return drv->process_label_set(label, use_default, on_exec); return drv->process_label_set(label, use_default, on_exec);
} }
/*
* _lsm_mount_proc: Mount /proc inside container to enable
* security domain transition
*
* @rootfs : the rootfs where proc should be mounted
*
* Returns < 0 on failure, 0 if the correct proc was already mounted
* and 1 if a new proc was mounted.
*/
static int _lsm_proc_mount(const char *rootfs)
{
char path[MAXPATHLEN];
char link[20];
int linklen, ret;
ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
if (ret < 0 || ret >= MAXPATHLEN) {
SYSERROR("proc path name too long");
return -1;
}
memset(link, 0, 20);
linklen = readlink(path, link, 20);
INFO("I am %d, /proc/self points to '%s'", getpid(), link);
ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs);
if (linklen < 0) /* /proc not mounted */
goto domount;
/* can't be longer than rootfs/proc/1 */
if (strncmp(link, "1", linklen) != 0) {
/* wrong /procs mounted */
umount2(path, MNT_DETACH); /* ignore failure */
goto domount;
}
/* the right proc is already mounted */
return 0;
domount:
if (mount("proc", path, "proc", 0, NULL))
return -1;
INFO("Mounted /proc in container for security transition");
return 1;
}
int lsm_proc_mount(struct lxc_conf *lxc_conf)
{
int mounted;
if (!drv || strcmp(drv->name, "nop") == 0)
return 0;
if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) {
if (mount("proc", "/proc", "proc", 0, NULL)) {
SYSERROR("Failed mounting /proc, proceeding");
mounted = 0;
} else
mounted = 1;
} else
mounted = _lsm_proc_mount(lxc_conf->rootfs.mount);
if (mounted == -1) {
SYSERROR("failed to mount /proc in the container.");
return -1;
} else if (mounted == 1) {
lxc_conf->lsm_umount_proc = 1;
}
return 0;
}
void lsm_proc_unmount(struct lxc_conf *lxc_conf)
{
if (lxc_conf->lsm_umount_proc == 1) {
umount("/proc");
lxc_conf->lsm_umount_proc = 0;
}
}
#endif #endif
...@@ -43,16 +43,12 @@ int lsm_enabled(void); ...@@ -43,16 +43,12 @@ int lsm_enabled(void);
const char *lsm_name(void); const char *lsm_name(void);
char *lsm_process_label_get(pid_t pid); char *lsm_process_label_get(pid_t pid);
int lsm_process_label_set(const char *label, int use_default, int on_exec); int lsm_process_label_set(const char *label, int use_default, int on_exec);
int lsm_proc_mount(struct lxc_conf *lxc_conf);
void lsm_proc_unmount(struct lxc_conf *lxc_conf);
#else #else
static inline void lsm_init(void) { } static inline void lsm_init(void) { }
static inline int lsm_enabled(void) { return 0; } static inline int lsm_enabled(void) { return 0; }
static inline const char *lsm_name(void) { return "none"; } static inline const char *lsm_name(void) { return "none"; }
static inline char *lsm_process_label_get(pid_t pid) { return NULL; } static inline char *lsm_process_label_get(pid_t pid) { return NULL; }
static inline int lsm_process_label_set(const char *label, int use_default, int on_exec) { return 0; } static inline int lsm_process_label_set(const char *label, int use_default, int on_exec) { return 0; }
static inline int lsm_proc_mount(struct lxc_conf *lxc_conf) { return 0; }
static inline void lsm_proc_unmount(struct lxc_conf *lxc_conf) { }
#endif #endif
#endif #endif
...@@ -649,7 +649,9 @@ static int do_start(void *data) ...@@ -649,7 +649,9 @@ static int do_start(void *data)
lsm_label = handler->conf->lsm_se_context; lsm_label = handler->conf->lsm_se_context;
if (lsm_process_label_set(lsm_label, 1, 1) < 0) if (lsm_process_label_set(lsm_label, 1, 1) < 0)
goto out_warn_father; goto out_warn_father;
lsm_proc_unmount(handler->conf);
/* If we mounted a temporary proc, then unmount it now */
tmp_proc_unmount(handler->conf);
if (lxc_seccomp_load(handler->conf) != 0) if (lxc_seccomp_load(handler->conf) != 0)
goto out_warn_father; goto out_warn_father;
......
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