Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec2aa8e8 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

userns: Allow the userns root to mount of devpts



- The context in which devpts is mounted has no effect on the creation
  of ptys as the /dev/ptmx interface has been used by unprivileged
  users for many years.

- Only support unprivileged mounts in combination with the newinstance
  option to ensure that mounting of /dev/pts in a user namespace will
  not allow the options of an existing mount of devpts to be modified.

- Create /dev/pts/ptmx as the root user in the user namespace that
  mounts devpts so that it's permissions to be changed.

Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent e11f0ae3
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -243,6 +243,13 @@ static int mknod_ptmx(struct super_block *sb)
	struct dentry *root = sb->s_root;
	struct dentry *root = sb->s_root;
	struct pts_fs_info *fsi = DEVPTS_SB(sb);
	struct pts_fs_info *fsi = DEVPTS_SB(sb);
	struct pts_mount_opts *opts = &fsi->mount_opts;
	struct pts_mount_opts *opts = &fsi->mount_opts;
	kuid_t root_uid;
	kgid_t root_gid;

	root_uid = make_kuid(current_user_ns(), 0);
	root_gid = make_kgid(current_user_ns(), 0);
	if (!uid_valid(root_uid) || !gid_valid(root_gid))
		return -EINVAL;


	mutex_lock(&root->d_inode->i_mutex);
	mutex_lock(&root->d_inode->i_mutex);


@@ -273,6 +280,8 @@ static int mknod_ptmx(struct super_block *sb)


	mode = S_IFCHR|opts->ptmxmode;
	mode = S_IFCHR|opts->ptmxmode;
	init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
	init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
	inode->i_uid = root_uid;
	inode->i_gid = root_gid;


	d_add(dentry, inode);
	d_add(dentry, inode);


@@ -438,6 +447,12 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type,
	if (error)
	if (error)
		return ERR_PTR(error);
		return ERR_PTR(error);


	/* Require newinstance for all user namespace mounts to ensure
	 * the mount options are not changed.
	 */
	if ((current_user_ns() != &init_user_ns) && !opts.newinstance)
		return ERR_PTR(-EINVAL);

	if (opts.newinstance)
	if (opts.newinstance)
		s = sget(fs_type, NULL, set_anon_super, flags, NULL);
		s = sget(fs_type, NULL, set_anon_super, flags, NULL);
	else
	else
@@ -491,6 +506,9 @@ static struct file_system_type devpts_fs_type = {
	.name		= "devpts",
	.name		= "devpts",
	.mount		= devpts_mount,
	.mount		= devpts_mount,
	.kill_sb	= devpts_kill_sb,
	.kill_sb	= devpts_kill_sb,
#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
	.fs_flags	= FS_USERNS_MOUNT | FS_USERNS_DEV_MOUNT,
#endif
};
};


/*
/*