OpenVZ Forum - RDF feed
type: channel
items: [patch 00/10] mount ownership and unprivileged mount syscall (v7)
items: [patch 01/10] unprivileged mounts: add user mounts to the kernel
items: [patch 03/10] unprivileged mounts: propagate error values from clone_mnt
items: [patch 04/10] unprivileged mounts: account user mounts
items: [patch 05/10] unprivileged mounts: allow unprivileged bind mounts
items: [patch 09/10] unprivileged mounts: propagation: inherit owner from parent
items: [patch 10/10] unprivileged mounts: add "no submounts" flag
items: Re: [patch 09/10] unprivileged mounts: propagation: inherit owner from parent

[patch 00/10] mount ownership and unprivileged mount syscall (v7)
type: item
description: Thanks to everyone for the comments on the previous submission. Christoph, could you please look through the patches if they are acceptable from the VFS point of view? Thanks, Miklos v6 -> v7: - add '/proc/sys/fs/types/<type>/usermount_safe' tunable (new patch) - do not make FUSE safe by default, describe possible problems associated with unprivileged FUSE mounts in patch header - return EMFILE instead of EPERM, if maximum user mount count is exceeded - rename option 'nomnt' -> 'nosubmnt' - clean up error propagation in dup_mnt_ns - update util-linux-ng patch v5 -> v6: - update to latest -mm - preliminary util-linux-ng support (will post right after this series) v4 -> v5: - fold back Andrew's changes - fold back my update patch: o use fsuid instead of ruid o allow forced unpriv. unmounts for "safe" filesystems o allow mounting over special files, but not over symlinks o set nosuid and nodev based on lack of specific capability - patch header updates - new patch: on propagation inherit owner from parent - new patch: add "no submounts" mount flag v3 -> v4: - simplify interface as much as possible, now only a single option ("user=UID") is used to control everything - no longer allow/deny mounting based on file/directory permissions, that approach does not always make sense v1 -> v3: - add mount flags to set/clear mnt_flags individually - add "usermnt" mount flag. If it is set, then allow unprivileged submounts under this mount - make max number of user mounts default to 1024, since now the usermnt flag will prevent user mounts by default -- _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: Miklos Szeredi
date: 2008-01-16T12:31:47-00:00

[patch 01/10] unprivileged mounts: add user mounts to the kernel
type: item
description: 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 cl…
creator: Miklos Szeredi
date: 2008-01-16T12:31:48-00:00

[patch 03/10] unprivileged mounts: propagate error values from clone_mnt
type: item
description: From: Miklos Szeredi <mszeredi@suse.cz> Allow clone_mnt() to return errors other than ENOMEM. This will be used for returning a different error value when the number of user mounts goes over the limit. Fix copy_tree() to return EPERM for unbindable mounts. 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-16 13:25:06.000000000 +0100 +++ linux/fs/namespace.c 2008-01-16 13:25:07.000000000 +0100 @@ -490,41 +490,42 @@ static struct vfsmount *clone_mnt(struct struct super_block *sb = old->mnt_sb; struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname); - if (mnt) { - mnt->mnt_flags = old->mnt_flags; - atomic_inc(&sb->s_active); - mnt->mnt_sb = sb; - mnt->mnt_root = dget(root); - 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; - CLEAR_MNT_SHARED(mnt); - } else if (!(flag & CL_PRIVATE)) { - if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) - list_add(&mnt->mnt_share, &old->mnt_share); - if (IS_MNT_SLAVE(old)) - list_add(&mnt->mnt_slave, &old->mnt_slave); - mnt->mnt_master = old->mnt_master; - } - if (flag & CL_MAKE_SHARED) - set_mnt_shared(mnt); + if (!mnt) + return ERR_PTR(-ENOMEM); - /* stick the duplicate mount on the same expiry list - * as the original if that was on one */ - if (flag & CL_EXPIRE) { - spin_lock(&vfsmount_lock); - if (!list_empty(&old->mnt_expire)) - list_add(&mnt->mnt_expire, &old->mnt_expire); - spin_unlock(&vfsmount_lock); - } + mnt->mnt_flags = old->mnt_flags; + atomic_inc(&sb->s_active); + mnt->mnt_sb = sb; + mnt->mnt_root = dget(root); + mnt->mnt_mountpoint = mnt->mnt_root; + mnt->mnt_parent = mnt; + + /* don't copy the MNT_USER flag */ + mnt-…
creator: Miklos Szeredi
date: 2008-01-16T12:31:50-00:00

[patch 04/10] unprivileged mounts: account user mounts
type: item
description: From: Miklos Szeredi <mszeredi@suse.cz> Add sysctl variables for accounting and limiting the number of user mounts. The maximum number of user mounts is set to 1024 by default. This won't in itself enable user mounts, setting a mount to be owned by a user is first needed. [akpm] - don't use enumerated sysctls Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Acked-by: Serge Hallyn <serue@us.ibm.com> --- Index: linux/Documentation/filesystems/proc.txt =================================================================== --- linux.orig/Documentation/filesystems/proc.txt 2008-01-16 13:24:53.000000000 +0100 +++ linux/Documentation/filesystems/proc.txt 2008-01-16 13:25:07.000000000 +0100 @@ -1012,6 +1012,15 @@ reaches aio-max-nr then io_setup will fa raising aio-max-nr does not result in the pre-allocation or re-sizing of any kernel data structures. +nr_user_mounts and max_user_mounts +---------------------------------- + +These represent the number of "user" mounts and the maximum number of +"user" mounts respectively. User mounts may be created by +unprivileged users. User mounts may also be created with sysadmin +privileges on behalf of a user, in which case nr_user_mounts may +exceed max_user_mounts. + 2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats ----------------------------------------------------------- Index: linux/fs/namespace.c =================================================================== --- linux.orig/fs/namespace.c 2008-01-16 13:25:07.000000000 +0100 +++ linux/fs/namespace.c 2008-01-16 13:25:07.000000000 +0100 @@ -44,6 +44,9 @@ static struct list_head *mount_hashtable static struct kmem_cache *mnt_cache __read_mostly; static struct rw_semaphore namespace_sem; +int nr_user_mounts; +int max_user_mounts = 1024; + /* /sys/fs */ struct kobject *fs_kobj; EXPORT_SYMBOL_GPL(fs_kobj); @@ -477,21 +480,70 @@ static struct vfsmount *skip_mnt_tree(st return p; } -static void set_mnt_user(struct vfsmount *mnt) +static void dec_nr_user_mounts(void) +{ + sp…
creator: Miklos Szeredi
date: 2008-01-16T12:31:51-00:00

[patch 05/10] unprivileged mounts: allow unprivileged bind mounts
type: item
description: 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-16 13:25:07.000000000 +0100 +++ linux/fs/namespace.c 2008-01-16 13:25:08.000000000 +0100 @@ -511,6 +511,11 @@ static void __set_mnt_user(struct vfsmou WARN_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) @@ -1021,22 +1026,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)) + retu…
creator: Miklos Szeredi
date: 2008-01-16T12:31:52-00:00

[patch 09/10] unprivileged mounts: propagation: inherit owner from parent
type: item
description: From: Miklos Szeredi <mszeredi@suse.cz> On mount propagation, let the owner of the clone be inherited from the parent into which it has been propagated. If the parent has the "nosuid" flag, set this flag for the child as well. This is needed for the suid-less namespace (use case #2 in the first patch header), where all mounts are owned by the user and have the nosuid flag set. In this case the propagated mount needs to have nosuid, otherwise a suid executable may be misused by the user. Similar treatment is not needed for "nodev", because devices can't be abused this way: the user is not able to gain privileges to devices by rearranging the mount namespace. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> --- Index: linux/fs/namespace.c =================================================================== --- linux.orig/fs/namespace.c 2008-01-16 13:25:09.000000000 +0100 +++ linux/fs/namespace.c 2008-01-16 13:25:11.000000000 +0100 @@ -506,10 +506,10 @@ static int reserve_user_mount(void) return err; } -static void __set_mnt_user(struct vfsmount *mnt) +static void __set_mnt_user(struct vfsmount *mnt, uid_t owner) { WARN_ON(mnt->mnt_flags & MNT_USER); - mnt->mnt_uid = current->fsuid; + mnt->mnt_uid = owner; mnt->mnt_flags |= MNT_USER; if (!capable(CAP_SETUID)) @@ -520,7 +520,7 @@ static void __set_mnt_user(struct vfsmou static void set_mnt_user(struct vfsmount *mnt) { - __set_mnt_user(mnt); + __set_mnt_user(mnt, current->fsuid); spin_lock(&vfsmount_lock); nr_user_mounts++; spin_unlock(&vfsmount_lock); @@ -536,7 +536,7 @@ static void clear_mnt_user(struct vfsmou } static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, - int flag) + int flag, uid_t owner) { struct super_block *sb = old->mnt_sb; struct vfsmount *mnt; @@ -560,7 +560,10 @@ 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, owner); + + if (flag & CL_NOSUID) + mnt->mnt_…
creator: Miklos Szeredi
date: 2008-01-16T12:31:56-00:00

[patch 10/10] unprivileged mounts: add "no submounts" flag
type: item
description: From: Miklos Szeredi <mszeredi@suse.cz> Add a new mount flag "nosubmnt", which denies submounts for the owner. This would be useful, if we want to support traditional /etc/fstab based user mounts. In this case mount(8) would still have to be suid-root, to check the mountpoint against the user/users flag in /etc/fstab, but /etc/mtab would no longer be mandatory for storing the actual owner of the mount. 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-16 13:25:11.000000000 +0100 +++ linux/fs/namespace.c 2008-01-16 13:25:12.000000000 +0100 @@ -700,6 +700,7 @@ static int show_vfsmnt(struct seq_file * { MNT_NOATIME, ",noatime" }, { MNT_NODIRATIME, ",nodiratime" }, { MNT_RELATIME, ",relatime" }, + { MNT_NOSUBMNT, ",nosubmnt" }, { 0, NULL } }; struct proc_fs_info *fs_infop; @@ -1050,6 +1051,9 @@ static bool permit_mount(struct nameidat if (S_ISLNK(inode->i_mode)) return false; + if (nd->path.mnt->mnt_flags & MNT_NOSUBMNT) + return false; + if (!is_mount_owner(nd->path.mnt, current->fsuid)) return false; @@ -1894,9 +1898,11 @@ long do_mount(char *dev_name, char *dir_ mnt_flags |= MNT_RELATIME; if (flags & MS_RDONLY) mnt_flags |= MNT_READONLY; + if (flags & MS_NOSUBMNT) + mnt_flags |= MNT_NOSUBMNT; - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | - MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); + flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_NOATIME | + MS_NODIRATIME | MS_RELATIME | MS_KERNMOUNT | MS_NOSUBMNT); /* ... and get the mountpoint */ retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); Index: linux/include/linux/fs.h =================================================================== --- linux.orig/include/linux/fs.h 2008-01-16 13:25:11.000000000 +0100 +++ linux/include/linux/fs.h 2008-01-16 13:25:12.000000000 +0100 @@ -129,6 +129,7 @@ extern int dir_no…
creator: Miklos Szeredi
date: 2008-01-16T12:31:57-00:00

Re: [patch 09/10] unprivileged mounts: propagation: inherit owner from parent
type: item
description: Quoting Miklos Szeredi (miklos@szeredi.hu): > From: Miklos Szeredi <mszeredi@suse.cz> > > On mount propagation, let the owner of the clone be inherited from the > parent into which it has been propagated. > > If the parent has the "nosuid" flag, set this flag for the child as > well. This is needed for the suid-less namespace (use case #2 in the > first patch header), where all mounts are owned by the user and have > the nosuid flag set. In this case the propagated mount needs to have > nosuid, otherwise a suid executable may be misused by the user. > > Similar treatment is not needed for "nodev", because devices can't be > abused this way: the user is not able to gain privileges to devices by > rearranging the mount namespace. > > Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> As discussed many months ago this does seem like the most appropriate behavior for propagation. Acked-by: Serge Hallyn <serue@us.ibm.com> > --- > > Index: linux/fs/namespace.c > =================================================================== > --- linux.orig/fs/namespace.c 2008-01-16 13:25:09.000000000 +0100 > +++ linux/fs/namespace.c 2008-01-16 13:25:11.000000000 +0100 > @@ -506,10 +506,10 @@ static int reserve_user_mount(void) > return err; > } > > -static void __set_mnt_user(struct vfsmount *mnt) > +static void __set_mnt_user(struct vfsmount *mnt, uid_t owner) > { > WARN_ON(mnt->mnt_flags & MNT_USER); > - mnt->mnt_uid = current->fsuid; > + mnt->mnt_uid = owner; > mnt->mnt_flags |= MNT_USER; > > if (!capable(CAP_SETUID)) > @@ -520,7 +520,7 @@ static void __set_mnt_user(struct vfsmou > > static void set_mnt_user(struct vfsmount *mnt) > { > - __set_mnt_user(mnt); > + __set_mnt_user(mnt, current->fsuid); > spin_lock(&vfsmount_lock); > nr_user_mounts++; > spin_unlock(&vfsmount_lock); > @@ -536,7 +536,7 @@ static void clear_mnt_user(struct vfsmou > } > > static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, > - int flag) > + int flag, uid_t owner) > { > struct super_…
creator: serue
date: 2008-01-21T20:23:06-00:00