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 1/9] unprivileged mounts: add user mounts to the kernel
Date: Mon, 14 Jan 2008 15:46:24 -0600 [thread overview]
Message-ID: <20080114214624.GA6704@sergelap.austin.ibm.com> (raw)
In-Reply-To: <20080108113619.213519920@szeredi.hu>
Quoting Miklos Szeredi (miklos@szeredi.hu):
> From: Miklos Szeredi <mszeredi@suse.cz>
>
> This patchset adds support for keeping mount ownership information in the
> kernel, and allow unprivileged mount(2) and umount(2) in certain cases.
>
> The mount owner has the following privileges:
>
> - unmount the owned mount
> - create a submount under the owned mount
>
> The sysadmin can set the owner explicitly on mount and remount. When an
> unprivileged user creates a mount, then the owner is automatically set to the
> user.
>
> The following use cases are envisioned:
>
> 1) Private namespace, with selected mounts owned by user. E.g.
> /home/$USER is a good candidate for allowing unpriv mounts and unmounts
> within.
>
> 2) Private namespace, with all mounts owned by user and having the "nosuid"
> flag. User can mount and umount anywhere within the namespace, but suid
> programs will not work.
>
> 3) Global namespace, with a designated directory, which is a mount owned by
> the user. E.g. /mnt/users/$USER is set up so that it is bind mounted onto
> itself, and set to be owned by $USER. The user can add/remove mounts only
> under this directory.
>
> The following extra security measures are taken for unprivileged mounts:
>
> - usermounts are limited by a sysctl tunable
> - force "nosuid,nodev" mount options on the created mount
>
> For testing unprivileged mounts (and for other purposes) simple
> mount/umount utilities are available from:
>
> http://www.kernel.org/pub/linux/kernel/people/mszeredi/mmount/
>
> After this series I'll be posting a preliminary patch for util-linux-ng,
> to add the same functionality to mount(8) and umount(8).
>
> This patch:
>
> A new mount flag, MS_SETUSER is used to make a mount owned by a user. If this
> flag is specified, then the owner will be set to the current fsuid and the
> mount will be marked with the MNT_USER flag. On remount don't preserve
> previous owner, and treat MS_SETUSER as for a new mount. The MS_SETUSER flag
> is ignored on mount move.
>
> The MNT_USER flag is not copied on any kind of mount cloning: namespace
> creation, binding or propagation. For bind mounts the cloned mount(s) are set
> to MNT_USER depending on the MS_SETUSER mount flag. In all the other cases
> MNT_USER is always cleared.
>
> For MNT_USER mounts a "user=UID" option is added to /proc/PID/mounts. This is
> compatible with how mount ownership is stored in /etc/mtab.
>
> The rationale for using MS_SETUSER and MNT_USER, to distinguish "user"
> mounts from "non-user" or "legacy" mounts are follows:
>
> a) Mount(2) and umount(2) on legacy mounts always need CAP_SYS_ADMIN
> capability. As opposed to user mounts, which will only require,
> that the mount owner matches the current fsuid. So a process
> with fsuid=0 should not be able to mount/umount legacy mounts
> without the CAP_SYS_ADMIN capability.
>
> b) Legacy userspace programs may set fsuid to nonzero before calling
> mount(2). In such an unlikely case, this patchset would cause
> an unintended side effect of making the mount owned by the fsuid.
>
> c) For legacy mounts, no "user=UID" option should be shown in
> /proc/mounts for backwards compatibility.
>
> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
This looks good to me.
Acked-by: Serge Hallyn <serue@us.ibm.com>
thanks,
-serge
> ---
>
> Index: linux/fs/namespace.c
> ===================================================================
> --- linux.orig/fs/namespace.c 2008-01-03 22:10:10.000000000 +0100
> +++ linux/fs/namespace.c 2008-01-04 13:46:33.000000000 +0100
> @@ -477,6 +477,13 @@ static struct vfsmount *skip_mnt_tree(st
> return p;
> }
>
> +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;
> +}
> +
> static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
> int flag)
> {
> @@ -491,6 +498,11 @@ static struct vfsmount *clone_mnt(struct
> mnt->mnt_mountpoint = mnt->mnt_root;
> mnt->mnt_parent = mnt;
>
> + /* don't copy the MNT_USER flag */
> + mnt->mnt_flags &= ~MNT_USER;
> + if (flag & CL_SETUSER)
> + set_mnt_user(mnt);
> +
> if (flag & CL_SLAVE) {
> list_add(&mnt->mnt_slave, &old->mnt_slave_list);
> mnt->mnt_master = old;
> @@ -644,6 +656,8 @@ static int show_vfsmnt(struct seq_file *
> if (mnt->mnt_flags & fs_infop->flag)
> seq_puts(m, fs_infop->str);
> }
> + if (mnt->mnt_flags & MNT_USER)
> + seq_printf(m, ",user=%i", mnt->mnt_uid);
> if (mnt->mnt_sb->s_op->show_options)
> err = mnt->mnt_sb->s_op->show_options(m, mnt);
> seq_puts(m, " 0 0\n");
> @@ -1181,8 +1195,9 @@ static int do_change_type(struct nameida
> /*
> * do loopback mount.
> */
> -static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
> +static int do_loopback(struct nameidata *nd, char *old_name, int flags)
> {
> + int clone_fl;
> struct nameidata old_nd;
> struct vfsmount *mnt = NULL;
> int err = mount_is_safe(nd);
> @@ -1202,11 +1217,12 @@ static int do_loopback(struct nameidata
> if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
> goto out;
>
> + clone_fl = (flags & MS_SETUSER) ? CL_SETUSER : 0;
> err = -ENOMEM;
> - if (recurse)
> - mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0);
> + if (flags & MS_REC)
> + mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, clone_fl);
> else
> - mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0);
> + mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, clone_fl);
>
> if (!mnt)
> goto out;
> @@ -1268,8 +1284,11 @@ static int do_remount(struct nameidata *
> err = change_mount_flags(nd->path.mnt, flags);
> else
> err = do_remount_sb(sb, flags, data, 0);
> - if (!err)
> + if (!err) {
> nd->path.mnt->mnt_flags = mnt_flags;
> + if (flags & MS_SETUSER)
> + set_mnt_user(nd->path.mnt);
> + }
> up_write(&sb->s_umount);
> if (!err)
> security_sb_post_remount(nd->path.mnt, flags, data);
> @@ -1378,10 +1397,13 @@ static int do_new_mount(struct nameidata
> if (!capable(CAP_SYS_ADMIN))
> return -EPERM;
>
> - mnt = do_kern_mount(type, flags, name, data);
> + mnt = do_kern_mount(type, flags & ~MS_SETUSER, name, data);
> if (IS_ERR(mnt))
> return PTR_ERR(mnt);
>
> + if (flags & MS_SETUSER)
> + set_mnt_user(mnt);
> +
> return do_add_mount(mnt, nd, mnt_flags, NULL);
> }
>
> @@ -1413,7 +1435,8 @@ int do_add_mount(struct vfsmount *newmnt
> if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
> goto unlock;
>
> - newmnt->mnt_flags = mnt_flags;
> + /* MNT_USER was set earlier */
> + newmnt->mnt_flags |= mnt_flags;
> if ((err = graft_tree(newmnt, nd)))
> goto unlock;
>
> @@ -1735,7 +1758,7 @@ long do_mount(char *dev_name, char *dir_
> retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
> data_page);
> else if (flags & MS_BIND)
> - retval = do_loopback(&nd, dev_name, flags & MS_REC);
> + retval = do_loopback(&nd, dev_name, flags);
> else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
> retval = do_change_type(&nd, flags);
> else if (flags & MS_MOVE)
> Index: linux/fs/pnode.h
> ===================================================================
> --- linux.orig/fs/pnode.h 2008-01-03 22:10:10.000000000 +0100
> +++ linux/fs/pnode.h 2008-01-04 13:45:45.000000000 +0100
> @@ -23,6 +23,7 @@
> #define CL_MAKE_SHARED 0x08
> #define CL_PROPAGATION 0x10
> #define CL_PRIVATE 0x20
> +#define CL_SETUSER 0x40
>
> static inline void set_mnt_shared(struct vfsmount *mnt)
> {
> Index: linux/include/linux/fs.h
> ===================================================================
> --- linux.orig/include/linux/fs.h 2008-01-03 22:10:10.000000000 +0100
> +++ linux/include/linux/fs.h 2008-01-04 13:45:46.000000000 +0100
> @@ -125,6 +125,7 @@ extern int dir_notify_enable;
> #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
> #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
> #define MS_I_VERSION (1<<23) /* Update inode I_version field */
> +#define MS_SETUSER (1<<24) /* set mnt_uid to current user */
> #define MS_ACTIVE (1<<30)
> #define MS_NOUSER (1<<31)
>
> Index: linux/include/linux/mount.h
> ===================================================================
> --- linux.orig/include/linux/mount.h 2008-01-03 22:10:10.000000000 +0100
> +++ linux/include/linux/mount.h 2008-01-04 13:45:45.000000000 +0100
> @@ -33,6 +33,7 @@ struct mnt_namespace;
>
> #define MNT_SHRINKABLE 0x100
> #define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */
> +#define MNT_USER 0x400
>
> #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
> #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
> @@ -69,6 +70,8 @@ struct vfsmount {
> * are held, and all mnt_writer[]s on this mount have 0 as their ->count
> */
> atomic_t __mnt_writers;
> +
> + uid_t mnt_uid; /* owner of the mount */
> };
>
> static inline struct vfsmount *mntget(struct vfsmount *mnt)
>
> --
next prev parent reply other threads:[~2008-01-14 21:46 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
[not found] ` <20080108113619.213519920-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-08 21:47 ` Pavel Machek
2008-01-14 21:46 ` Serge E. Hallyn [this message]
2008-01-08 11:35 ` [patch 2/9] unprivileged mounts: allow unprivileged umount Miklos Szeredi
[not found] ` <20080108113620.664824939-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-14 21:48 ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 3/9] unprivileged mounts: account user mounts Miklos Szeredi
[not found] ` <20080108113623.446872155-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
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
[not found] ` <20080108113624.898035951-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
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
[not found] ` <E1JCJoQ-0003g9-Nk-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
2008-01-08 19:15 ` Dave Hansen
2008-01-08 20:44 ` Szabolcs Szakacsits
2008-01-09 12:45 ` Jan Engelhardt
[not found] ` <Pine.LNX.4.64.0801091340270.29244-vVwEwcwQeYFPkBl3ERsXe1l1cybopEuJUBSOeVevoDU@public.gmane.org>
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
[not found] ` <20080108113626.895583537-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-10 4:47 ` Serge E. Hallyn
2008-01-14 22:42 ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 6/9] unprivileged mounts: allow unprivileged mounts Miklos Szeredi
2008-01-09 11:11 ` Karel Zak
[not found] ` <20080109111120.GI3926-CxBs/XhZ2BtHjqfyn1fVYA@public.gmane.org>
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
[not found] ` <20080108214625.GE5050-+ZI9xUNit7I@public.gmane.org>
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
[not found] ` <E1JCbIb-0005rA-5O-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
2008-01-09 14:00 ` Pavel Machek
2008-01-09 14:14 ` Miklos Szeredi
2008-01-08 23:56 ` Nigel Cunningham
[not found] ` <47840DAC.5000108-MhVfhJ0qHmuWn91e4EydUaxOck334EZe@public.gmane.org>
2008-01-09 8:47 ` Miklos Szeredi
[not found] ` <E1JCWax-0005Ck-Kg-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
2008-01-09 9:29 ` Nigel Cunningham
2008-01-09 11:12 ` Pavel Machek
2008-01-09 9:19 ` Szabolcs Szakacsits
[not found] ` <20080108113630.861045063-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-14 23:24 ` Serge E. Hallyn
2008-01-15 10:29 ` Miklos Szeredi
[not found] ` <E1JEj3N-0000vj-QA-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
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
[not found] ` <20080108113632.895453887-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-14 23:13 ` Serge E. Hallyn
2008-01-15 10:39 ` Miklos Szeredi
[not found] ` <E1JEjCG-0000wz-BS-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
2008-01-15 14:21 ` Serge E. Hallyn
2008-01-15 14:37 ` Miklos Szeredi
[not found] ` <E1JEmv3-0001RN-6J-8f8m9JG5TPIdUIPVzhDTVZP2KDSNp7ea@public.gmane.org>
2008-01-15 14:59 ` Serge E. Hallyn
2008-01-08 11:35 ` [patch 9/9] unprivileged mounts: add "no submounts" flag Miklos Szeredi
[not found] ` <20080108113634.382855604-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>
2008-01-14 23:39 ` Serge E. Hallyn
2008-01-15 10:41 ` Miklos Szeredi
2008-01-15 10:53 ` A. C. Censi
[not found] ` <643ea2b10801150253i735d7342q73bf01f864d6167c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
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=20080114214624.GA6704@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;
as well as URLs for NNTP newsgroup(s).