diff --git a/src/lxc/conf.c b/src/lxc/conf.c index eb92b5cd4..5d4740697 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3760,20 +3760,21 @@ int ttys_shift_ids(struct lxc_conf *c) return 0; } -/* NOTE: not to be called from inside the container namespace! */ -int tmp_proc_mount(struct lxc_conf *lxc_conf) +/* NOTE: Must not be called from inside the container namespace! */ +int lxc_create_tmp_proc_mount(struct lxc_conf *conf) { int mounted; - mounted = mount_proc_if_needed(lxc_conf->rootfs.path ? lxc_conf->rootfs.mount : ""); + mounted = lxc_mount_proc_if_needed(conf->rootfs.path ? conf->rootfs.mount : ""); if (mounted == -1) { - SYSERROR("failed to mount /proc in the container."); + SYSERROR("failed to mount /proc in the container"); /* continue only if there is no rootfs */ - if (lxc_conf->rootfs.path) + if (conf->rootfs.path) return -1; } else if (mounted == 1) { - lxc_conf->tmp_umount_proc = 1; + conf->tmp_umount_proc = 1; } + return 0; } @@ -4063,7 +4064,7 @@ int lxc_setup(struct lxc_handler *handler) } /* mount /proc if it's not already there */ - if (tmp_proc_mount(lxc_conf) < 0) { + if (lxc_create_tmp_proc_mount(lxc_conf) < 0) { ERROR("failed to LSM mount proc for '%s'", name); return -1; } diff --git a/src/lxc/utils.c b/src/lxc/utils.c index d83e294fa..6458bbdce 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -1754,7 +1754,7 @@ int safe_mount(const char *src, const char *dest, const char *fstype, * * NOTE: not to be called from inside the container namespace! */ -int mount_proc_if_needed(const char *rootfs) +int lxc_mount_proc_if_needed(const char *rootfs) { char path[MAXPATHLEN]; char link[20]; @@ -1766,37 +1766,48 @@ int mount_proc_if_needed(const char *rootfs) SYSERROR("proc path name too long"); return -1; } + memset(link, 0, 20); linklen = readlink(path, link, 20); mypid = (int)getpid(); - INFO("I am %d, /proc/self points to '%s'", mypid, link); + INFO("I am %d, /proc/self points to \"%s\"", mypid, link); + ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs); if (ret < 0 || ret >= MAXPATHLEN) { SYSERROR("proc path name too long"); return -1; } - if (linklen < 0) /* /proc not mounted */ - goto domount; - if (lxc_safe_int(link, &link_to_pid) < 0) - return -1; - if (link_to_pid != mypid) { - /* wrong /procs mounted */ - umount2(path, MNT_DETACH); /* ignore failure */ + + /* /proc not mounted */ + if (linklen < 0) { + if (mkdir(path, 0755) && errno != EEXIST) + return -1; goto domount; } + + if (lxc_safe_int(link, &link_to_pid) < 0) + return -1; + + /* wrong /procs mounted */ + if (link_to_pid != mypid) { + /* ignore failure */ + umount2(path, MNT_DETACH); + goto domount; + } + /* the right proc is already mounted */ return 0; domount: - if (!strcmp(rootfs,"")) /* rootfs is NULL */ + /* rootfs is NULL */ + if (!strcmp(rootfs,"")) ret = mount("proc", path, "proc", 0, NULL); else ret = safe_mount("proc", path, "proc", 0, NULL, rootfs); - if (ret < 0) return -1; - INFO("Mounted /proc in container for security transition"); + INFO("mounted /proc in container for security transition"); return 1; } diff --git a/src/lxc/utils.h b/src/lxc/utils.h index b6fc7c5fa..161788f98 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -326,7 +326,7 @@ char *get_template_path(const char *t); int setproctitle(char *title); int safe_mount(const char *src, const char *dest, const char *fstype, unsigned long flags, const void *data, const char *rootfs); -int mount_proc_if_needed(const char *rootfs); +int lxc_mount_proc_if_needed(const char *rootfs); int open_devnull(void); int set_stdfds(int fd); int null_stdfds(void);