[CRIU] [PATCH 2/2] tty: check that a master of a bind-mounted slave is in the root mntns
Pavel Emelyanov
xemul at virtuozzo.com
Mon Feb 27 10:23:31 PST 2017
On 02/22/2017 09:39 AM, Andrei Vagin wrote:
> From: Andrei Vagin <avagin at virtuozzo.com>
>
> Here we check that a master of a bind-mounted slave was opened in the
> root mount namespace. The problem is that we restore all mounts in the
> root mount namespace. Only when all mounts are restored, we create other
> mount namespaces. So when we are restoring mounts, we can open files
> only in the root mount namespace.
>
> Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
> ---
> criu/filesystems.c | 1 +
> criu/include/filesystems.h | 1 +
> criu/include/tty.h | 2 ++
> criu/mount.c | 4 ++++
> criu/tty.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 67 insertions(+)
>
> diff --git a/criu/filesystems.c b/criu/filesystems.c
> index 4688d1f..1ab8599 100644
> --- a/criu/filesystems.c
> +++ b/criu/filesystems.c
> @@ -700,6 +700,7 @@ static struct fstype fstypes[] = {
> .parse = devpts_parse,
> .code = FSTYPE__DEVPTS,
> .restore = devpts_restore,
> + .dump_bindmount = devpts_dump_bindmount,
It's not 'dump_bindmount', but rather 'check_bindmount'.
Other than this Ack on the series.
> }, {
> .name = "simfs",
> .code = FSTYPE__SIMFS,
> diff --git a/criu/include/filesystems.h b/criu/include/filesystems.h
> index 5aea32d..be270fa 100644
> --- a/criu/include/filesystems.h
> +++ b/criu/include/filesystems.h
> @@ -13,6 +13,7 @@ struct fstype {
> int code;
> int (*dump)(struct mount_info *pm);
> int (*restore)(struct mount_info *pm);
> + int (*dump_bindmount)(struct mount_info *pm);
> int (*parse)(struct mount_info *pm);
> int (*collect)(struct mount_info *pm);
> bool (*sb_equal)(struct mount_info *a, struct mount_info *b);
> diff --git a/criu/include/tty.h b/criu/include/tty.h
> index 4656038..54bc142 100644
> --- a/criu/include/tty.h
> +++ b/criu/include/tty.h
> @@ -37,6 +37,8 @@ extern void tty_fini_fds(void);
>
> extern int tty_restore_ctl_terminal(struct file_desc *d, int fd);
>
> +extern int devpts_dump_bindmount(struct mount_info *m);
> +
> #define OPT_SHELL_JOB "shell-job"
>
> #endif /* __CR_TTY_H__ */
> diff --git a/criu/mount.c b/criu/mount.c
> index 5520b23..531cb3e 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -1267,6 +1267,10 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
> if (!pm->dumped && dump_one_fs(pm))
> return -1;
>
> + if (!fsroot_mounted(pm) &&
> + pm->fstype->dump_bindmount && pm->fstype->dump_bindmount(pm))
> + return -1;
> +
> if (pm->mnt_id == CRTIME_MNT_ID) {
> pr_info("Skip dumping cr-time mountpoint: %s\n", pm->mountpoint);
> return 0;
> diff --git a/criu/tty.c b/criu/tty.c
> index bd861e9..62da7a1 100644
> --- a/criu/tty.c
> +++ b/criu/tty.c
> @@ -115,6 +115,7 @@ struct tty_dump_info {
> pid_t sid;
> pid_t pgrp;
> int fd;
> + int mnt_id;
> struct tty_driver *driver;
>
> int index;
> @@ -1755,6 +1756,7 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, struct tty_d
> dinfo->sid = pti->sid;
> dinfo->pgrp = pti->pgrp;
> dinfo->fd = p->fd;
> + dinfo->mnt_id = p->mnt_id;
> dinfo->driver = driver;
> dinfo->flags = p->flags;
>
> @@ -2182,6 +2184,63 @@ static int pty_create_ptmx_index(int dfd, int index, int flags)
> return 0;
> }
>
> +/*
> + * Here we check that a master of a bind-mounted slave was opened in the root
> + * mount namespace. The problem is that we restore all mounts in the root mount
> + * namespace. Only when all mounts are restored, we create other mount
> + * namespaces. So when we are restoring mounts, we can open files only in the
> + * root mount namespace.
> + */
> +int devpts_dump_bindmount(struct mount_info *m)
> +{
> + struct tty_dump_info *dinfo = NULL;
> + struct mount_info *master_mp;
> + int index;
> +
> + if (strcmp(m->root, "/") == 0 || strcmp(m->root, "/ptmx") == 0)
> + return 0;
> +
> + if (sscanf(m->root, "/%d", &index) != 1) {
> + pr_err("Unable to parse %s", m->root);
> + return -1;
> + }
> +
> + list_for_each_entry(dinfo, &all_ttys, list) {
> + if (!is_pty(dinfo->driver))
> + continue;
> +
> + if (dinfo->driver->subtype != TTY_SUBTYPE_MASTER)
> + continue;
> +
> + if (dinfo->index == index)
> + goto found;
> + }
> +
> + if (opts.orphan_pts_master) /* external master */
> + return 0;
> +
> + pr_err("Unable to find a master for %s\n", m->root);
> + return -1;
> +
> +found:
> + /* mnt_id isn't reported in fdinfo, so here is only one mntns */
> + if (dinfo->mnt_id == -1)
> + return 0;
> +
> + master_mp = lookup_mnt_id(dinfo->mnt_id);
> + if (!master_mp) {
> + pr_err("Unable to find a mount %d\n", dinfo->mnt_id);
> + return -1;
> + }
> +
> + if (master_mp->nsid->type != NS_ROOT) {
> + pr_err("The master for %s isn't from the root mntns", m->root);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> /* Restore slave pty-s which have to be bind-mounted to somewhere */
> int devpts_restore(struct mount_info *pm)
> {
>
More information about the CRIU
mailing list