[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