mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: akpm@linux-foundation.org, hch@infradead.org, serue@us.ibm.com,
	viro@ftp.linux.org.uk, ebiederm@xmission.com, kzak@redhat.com,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	containers@lists.osdl.org, util-linux-ng@vger.kernel.org
Subject: Re: [patch 5/9] unprivileged mounts: allow unprivileged bind mounts
Date: Mon, 14 Jan 2008 16:42:40 -0600	[thread overview]
Message-ID: <20080114224240.GE6704@sergelap.austin.ibm.com> (raw)
In-Reply-To: <20080108113626.895583537@szeredi.hu>

Quoting Miklos Szeredi (miklos@szeredi.hu):
> From: Miklos Szeredi <mszeredi@suse.cz>
> 
> Allow bind mounts to unprivileged users if the following conditions are met:
> 
>   - mountpoint is not a symlink
>   - parent mount is owned by the user
>   - the number of user mounts is below the maximum
> 
> Unprivileged mounts imply MS_SETUSER, and will also have the "nosuid" and
> "nodev" mount flags set.
> 
> In particular, if mounting process doesn't have CAP_SETUID capability,
> then the "nosuid" flag will be added, and if it doesn't have CAP_MKNOD
> capability, then the "nodev" flag will be added.
> 
> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

Acked-by: Serge Hallyn <serue@us.ibm.com>

> ---
> 
> Index: linux/fs/namespace.c
> ===================================================================
> --- linux.orig/fs/namespace.c	2008-01-04 13:47:49.000000000 +0100
> +++ linux/fs/namespace.c	2008-01-04 13:48:01.000000000 +0100
> @@ -487,11 +487,34 @@ static void dec_nr_user_mounts(void)
>  	spin_unlock(&vfsmount_lock);
>  }
> 
> -static void set_mnt_user(struct vfsmount *mnt)
> +static int reserve_user_mount(void)
> +{
> +	int err = 0;
> +
> +	spin_lock(&vfsmount_lock);
> +	if (nr_user_mounts >= max_user_mounts && !capable(CAP_SYS_ADMIN))
> +		err = -EPERM;
> +	else
> +		nr_user_mounts++;
> +	spin_unlock(&vfsmount_lock);
> +	return err;
> +}
> +
> +static void __set_mnt_user(struct vfsmount *mnt)
>  {
>  	BUG_ON(mnt->mnt_flags & MNT_USER);
>  	mnt->mnt_uid = current->fsuid;
>  	mnt->mnt_flags |= MNT_USER;
> +
> +	if (!capable(CAP_SETUID))
> +		mnt->mnt_flags |= MNT_NOSUID;
> +	if (!capable(CAP_MKNOD))
> +		mnt->mnt_flags |= MNT_NODEV;
> +}
> +
> +static void set_mnt_user(struct vfsmount *mnt)
> +{
> +	__set_mnt_user(mnt);
>  	spin_lock(&vfsmount_lock);
>  	nr_user_mounts++;
>  	spin_unlock(&vfsmount_lock);
> @@ -510,10 +533,16 @@ static struct vfsmount *clone_mnt(struct
>  					int flag)
>  {
>  	struct super_block *sb = old->mnt_sb;
> -	struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
> +	struct vfsmount *mnt;
> 
> +	if (flag & CL_SETUSER) {
> +		int err = reserve_user_mount();
> +		if (err)
> +			return ERR_PTR(err);
> +	}
> +	mnt = alloc_vfsmnt(old->mnt_devname);
>  	if (!mnt)
> -		return ERR_PTR(-ENOMEM);
> +		goto alloc_failed;
> 
>  	mnt->mnt_flags = old->mnt_flags;
>  	atomic_inc(&sb->s_active);
> @@ -525,7 +554,7 @@ static struct vfsmount *clone_mnt(struct
>  	/* don't copy the MNT_USER flag */
>  	mnt->mnt_flags &= ~MNT_USER;
>  	if (flag & CL_SETUSER)
> -		set_mnt_user(mnt);
> +		__set_mnt_user(mnt);
> 
>  	if (flag & CL_SLAVE) {
>  		list_add(&mnt->mnt_slave, &old->mnt_slave_list);
> @@ -550,6 +579,11 @@ static struct vfsmount *clone_mnt(struct
>  		spin_unlock(&vfsmount_lock);
>  	}
>  	return mnt;
> +
> + alloc_failed:
> +	if (flag & CL_SETUSER)
> +		dec_nr_user_mounts();
> +	return ERR_PTR(-ENOMEM);
>  }
> 
>  static inline void __mntput(struct vfsmount *mnt)
> @@ -986,22 +1020,26 @@ asmlinkage long sys_oldumount(char __use
> 
>  #endif
> 
> -static int mount_is_safe(struct nameidata *nd)
> +/*
> + * Conditions for unprivileged mounts are:
> + * - mountpoint is not a symlink
> + * - mountpoint is in a mount owned by the user
> + */
> +static bool permit_mount(struct nameidata *nd, int *flags)
>  {
> +	struct inode *inode = nd->path.dentry->d_inode;
> +
>  	if (capable(CAP_SYS_ADMIN))
> -		return 0;
> -	return -EPERM;
> -#ifdef notyet
> -	if (S_ISLNK(nd->path.dentry->d_inode->i_mode))
> -		return -EPERM;
> -	if (nd->path.dentry->d_inode->i_mode & S_ISVTX) {
> -		if (current->uid != nd->path.dentry->d_inode->i_uid)
> -			return -EPERM;
> -	}
> -	if (vfs_permission(nd, MAY_WRITE))
> -		return -EPERM;
> -	return 0;
> -#endif
> +		return true;
> +
> +	if (S_ISLNK(inode->i_mode))
> +		return false;
> +
> +	if (!is_mount_owner(nd->path.mnt, current->fsuid))
> +		return false;
> +
> +	*flags |= MS_SETUSER;
> +	return true;
>  }
> 
>  static int lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
> @@ -1245,9 +1283,10 @@ static int do_loopback(struct nameidata 
>  	int clone_fl;
>  	struct nameidata old_nd;
>  	struct vfsmount *mnt = NULL;
> -	int err = mount_is_safe(nd);
> -	if (err)
> -		return err;
> +	int err;
> +
> +	if (!permit_mount(nd, &flags))
> +		return -EPERM;
>  	if (!old_name || !*old_name)
>  		return -EINVAL;
>  	err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
> 
> --

  parent reply	other threads:[~2008-01-14 22:42 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-08 11:35 [patch 0/9] mount ownership and unprivileged mount syscall (v6) Miklos Szeredi
2008-01-08 11:35 ` [patch 1/9] unprivileged mounts: add user mounts to the kernel Miklos Szeredi
2008-01-08 21:34   ` Pavel Machek
2008-01-08 21:47   ` Pavel Machek
2008-01-14 21:46   ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 2/9] unprivileged mounts: allow unprivileged umount Miklos Szeredi
2008-01-14 21:48   ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 3/9] unprivileged mounts: account user mounts Miklos Szeredi
2008-01-08 18:18   ` Dave Hansen
2008-01-08 19:18     ` Miklos Szeredi
2008-01-14 21:53   ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 4/9] unprivileged mounts: propagate error values from clone_mnt Miklos Szeredi
2008-01-14 22:23   ` Serge E. Hallyn
2008-01-15 10:15     ` Miklos Szeredi
2008-01-08 11:35 ` [patch 5/9] unprivileged mounts: allow unprivileged bind mounts Miklos Szeredi
2008-01-08 18:12   ` Dave Hansen
2008-01-08 19:08     ` Miklos Szeredi
2008-01-08 19:15       ` Dave Hansen
2008-01-08 20:44       ` Szabolcs Szakacsits
2008-01-09 12:45       ` Jan Engelhardt
2008-01-09 13:26         ` Karel Zak
2008-01-09 13:32           ` Miklos Szeredi
2008-01-08 18:26   ` Dave Hansen
2008-01-08 19:21     ` Miklos Szeredi
2008-01-10  4:47   ` Serge E. Hallyn
2008-01-14 22:42   ` Serge E. Hallyn [this message]
2008-01-08 11:35 ` [patch 6/9] unprivileged mounts: allow unprivileged mounts Miklos Szeredi
2008-01-09 11:11   ` Karel Zak
2008-01-09 12:41     ` Miklos Szeredi
2008-01-14 22:58   ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 7/9] unprivileged mounts: allow unprivileged fuse mounts Miklos Szeredi
2008-01-08 21:46   ` Pavel Machek
2008-01-08 22:42     ` Miklos Szeredi
2008-01-08 22:58       ` Pavel Machek
2008-01-09  9:11         ` Miklos Szeredi
2008-01-09 11:33           ` Pavel Machek
2008-01-09 13:16             ` Miklos Szeredi
2008-01-09 13:35               ` Pavel Machek
2008-01-09 13:48                 ` Miklos Szeredi
2008-01-09 14:00                   ` Pavel Machek
2008-01-09 14:14                     ` Miklos Szeredi
2008-01-08 23:56       ` Nigel Cunningham
2008-01-09  8:47         ` Miklos Szeredi
2008-01-09  9:29           ` Nigel Cunningham
2008-01-09 11:12           ` Pavel Machek
2008-01-09  9:19         ` Szabolcs Szakacsits
2008-01-14 23:24   ` Serge E. Hallyn
2008-01-15 10:29     ` Miklos Szeredi
2008-01-15 13:35       ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 8/9] unprivileged mounts: propagation: inherit owner from parent Miklos Szeredi
2008-01-14 23:13   ` Serge E. Hallyn
2008-01-15 10:39     ` Miklos Szeredi
2008-01-15 14:21       ` Serge E. Hallyn
2008-01-15 14:37         ` Miklos Szeredi
2008-01-15 14:59           ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 9/9] unprivileged mounts: add "no submounts" flag Miklos Szeredi
2008-01-14 23:39   ` Serge E. Hallyn
2008-01-15 10:41     ` Miklos Szeredi
2008-01-15 10:53       ` A. C. Censi
2008-01-15 10:58         ` Miklos Szeredi
2008-01-15 13:47           ` Serge E. Hallyn
2008-01-16  9:43             ` Miklos Szeredi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080114224240.GE6704@sergelap.austin.ibm.com \
    --to=serue@us.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=containers@lists.osdl.org \
    --cc=ebiederm@xmission.com \
    --cc=hch@infradead.org \
    --cc=kzak@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=util-linux-ng@vger.kernel.org \
    --cc=viro@ftp.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®