[lxc-devel] [PATCH 1/1] always check whether rootfs is shared
Dwight Engen
dwight.engen at oracle.com
Tue Feb 25 14:16:15 UTC 2014
On Mon, 24 Feb 2014 23:08:26 -0600
Serge Hallyn <serge.hallyn at ubuntu.com> wrote:
> (this expands on Dwight's recent patch, commit c597baa8f9)
>
> After unshare(CLONE_NEWNS) and before doing any mounting, always
> check whether rootfs is shared. Otherwise template runs or clone
> scripts can bleed mount activity to the host.
>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Acked-by: Dwight Engen <dwight.engen at oracle.com>
(You might want to change/genericize the error message since those
are not rsync)
> ---
> src/lxc/attach.c | 7 +++++++
> src/lxc/bdev.c | 7 +++++++
> src/lxc/conf.c | 40
> ---------------------------------------- src/lxc/lxc_usernsexec.c |
> 7 +++++++ src/lxc/lxccontainer.c | 6 ++++++
> src/lxc/utils.c | 40
> ++++++++++++++++++++++++++++++++++++++++ src/lxc/utils.h |
> 2 ++ 7 files changed, 69 insertions(+), 40 deletions(-)
>
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index f12d216..9136ec2 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -220,6 +220,13 @@ static int lxc_attach_remount_sys_proc(void)
> return -1;
> }
>
> + if (detect_shared_rootfs()) {
> + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
> + SYSERROR("Failed to make / rslave to run
> rsync");
> + ERROR("Continuing...");
> + }
> + }
> +
> /* assume /proc is always mounted, so remount it */
> ret = umount2("/proc", MNT_DETACH);
> if (ret < 0) {
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index 952cfeb..40f70c5 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -302,6 +302,13 @@ static int detect_fs(struct bdev *bdev, char
> *type, int len) if (unshare(CLONE_NEWNS) < 0)
> exit(1);
>
> + if (detect_shared_rootfs()) {
> + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
> + SYSERROR("Failed to make / rslave to run
> rsync");
> + ERROR("Continuing...");
> + }
> + }
> +
> ret = mount_unknown_fs(srcdev, bdev->dest, bdev->mntopts);
> if (ret < 0) {
> ERROR("failed mounting %s onto %s to detect fstype",
> srcdev, bdev->dest); diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index c9dd7ac..fc39897 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -1427,46 +1427,6 @@ static int setup_autodev(const char *root)
> }
>
> /*
> - * Detect whether / is mounted MS_SHARED. The only way I know of to
> - * check that is through /proc/self/mountinfo.
> - * I'm only checking for /. If the container rootfs or mount
> location
> - * is MS_SHARED, but not '/', then you're out of luck - figuring that
> - * out would be too much work to be worth it.
> - */
> -#define LINELEN 4096
> -int detect_shared_rootfs(void)
> -{
> - char buf[LINELEN], *p;
> - FILE *f;
> - int i;
> - char *p2;
> -
> - f = fopen("/proc/self/mountinfo", "r");
> - if (!f)
> - return 0;
> - while (fgets(buf, LINELEN, f)) {
> - for (p = buf, i=0; p && i < 4; i++)
> - p = index(p+1, ' ');
> - if (!p)
> - continue;
> - p2 = index(p+1, ' ');
> - if (!p2)
> - continue;
> - *p2 = '\0';
> - if (strcmp(p+1, "/") == 0) {
> - // this is '/'. is it shared?
> - p = index(p2+1, ' ');
> - if (p && strstr(p, "shared:")) {
> - fclose(f);
> - return 1;
> - }
> - }
> - }
> - fclose(f);
> - return 0;
> -}
> -
> -/*
> * I'll forgive you for asking whether all of this is needed :) The
> * answer is yes.
> * pivot_root will fail if the new root, the put_old dir, or the
> parent diff --git a/src/lxc/lxc_usernsexec.c
> b/src/lxc/lxc_usernsexec.c index e40fa53..6784633 100644
> --- a/src/lxc/lxc_usernsexec.c
> +++ b/src/lxc/lxc_usernsexec.c
> @@ -35,6 +35,7 @@
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> +#include <sys/mount.h>
> #include <sys/wait.h>
> #include <sched.h>
> #include <pwd.h>
> @@ -111,6 +112,12 @@ static int do_child(void *vargv)
> perror("unshare CLONE_NEWNS");
> return -1;
> }
> + if (detect_shared_rootfs()) {
> + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
> + printf("Failed to make / rslave to run
> rsync");
> + return -1;
> + }
> + }
> execvp(argv[0], argv);
> perror("execvpe");
> return -1;
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 0d89d11..8eb2d8b 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -2502,6 +2502,12 @@ static int clone_update_rootfs(struct
> clone_update_data *data) bdev_put(bdev);
> return -1;
> }
> + if (detect_shared_rootfs()) {
> + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC,
> NULL)) {
> + SYSERROR("Failed to make / rslave to
> run rsync");
> + ERROR("Continuing...");
> + }
> + }
> if (bdev->ops->mount(bdev) < 0) {
> bdev_put(bdev);
> return -1;
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index 52e4c86..da7c3b4 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -1194,3 +1194,43 @@ uint64_t fnv_64a_buf(void *buf, size_t len,
> uint64_t hval)
> return hval;
> }
> +
> +/*
> + * Detect whether / is mounted MS_SHARED. The only way I know of to
> + * check that is through /proc/self/mountinfo.
> + * I'm only checking for /. If the container rootfs or mount
> location
> + * is MS_SHARED, but not '/', then you're out of luck - figuring that
> + * out would be too much work to be worth it.
> + */
> +#define LINELEN 4096
> +int detect_shared_rootfs(void)
> +{
> + char buf[LINELEN], *p;
> + FILE *f;
> + int i;
> + char *p2;
> +
> + f = fopen("/proc/self/mountinfo", "r");
> + if (!f)
> + return 0;
> + while (fgets(buf, LINELEN, f)) {
> + for (p = buf, i=0; p && i < 4; i++)
> + p = index(p+1, ' ');
> + if (!p)
> + continue;
> + p2 = index(p+1, ' ');
> + if (!p2)
> + continue;
> + *p2 = '\0';
> + if (strcmp(p+1, "/") == 0) {
> + // this is '/'. is it shared?
> + p = index(p2+1, ' ');
> + if (p && strstr(p, "shared:")) {
> + fclose(f);
> + return 1;
> + }
> + }
> + }
> + fclose(f);
> + return 0;
> +}
> diff --git a/src/lxc/utils.h b/src/lxc/utils.h
> index f6f3373..dcf0e34 100644
> --- a/src/lxc/utils.h
> +++ b/src/lxc/utils.h
> @@ -276,3 +276,5 @@ extern bool dir_exists(const char *path);
> #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
> uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval);
> #endif
> +
> +int detect_shared_rootfs(void);
More information about the lxc-devel
mailing list