summaryrefslogtreecommitdiff
path: root/fs/namei.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 15:21:19 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 15:21:19 -0700
commitd8aed8415b861d5b829742608400f772559b6739 (patch)
tree191ea5d9f6a6077addbe0cab2c3a47aa4acf7cf2 /fs/namei.c
parent325520142b47690018d09060a874327d5e7f0709 (diff)
parentf3f1a18330ac1b717cd7a32adff38d965f365aa2 (diff)
downloadlwn-d8aed8415b861d5b829742608400f772559b6739.tar.gz
lwn-d8aed8415b861d5b829742608400f772559b6739.zip
Merge branch 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull userns updates from Eric Biederman: "This is the last couple of vfs bits to enable root in a user namespace to mount and manipulate a filesystem with backing store (AKA not a virtual filesystem like proc, but a filesystem where the unprivileged user controls the content). The target filesystem for this work is fuse, and Miklos should be sending you the pull request for the fuse bits this merge window. The two key patches are "evm: Don't update hmacs in user ns mounts" and "vfs: Don't allow changing the link count of an inode with an invalid uid or gid". Those close small gaps in the vfs that would be a problem if an unprivileged fuse filesystem is mounted. The rest of the changes are things that are now safe to allow a root user in a user namespace to do with a filesystem they have mounted. The most interesting development is that remount is now safe" * 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw filesystems capabilities: Allow privileged user in s_user_ns to set security.* xattrs fs: Allow superblock owner to access do_remount_sb() fs: Allow superblock owner to replace invalid owners of inodes vfs: Allow userns root to call mknod on owned filesystems. vfs: Don't allow changing the link count of an inode with an invalid uid or gid evm: Don't update hmacs in user ns mounts
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/namei.c b/fs/namei.c
index a59968de1636..6df1f61855d6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -984,13 +984,15 @@ static bool safe_hardlink_source(struct inode *inode)
*/
static int may_linkat(struct path *link)
{
- struct inode *inode;
+ struct inode *inode = link->dentry->d_inode;
+
+ /* Inode writeback is not safe when the uid or gid are invalid. */
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EOVERFLOW;
if (!sysctl_protected_hardlinks)
return 0;
- inode = link->dentry->d_inode;
-
/* Source inode owner (or CAP_FOWNER) can hardlink all they like,
* otherwise, it must be a safe source.
*/
@@ -2747,6 +2749,11 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
BUG_ON(!inode);
BUG_ON(victim->d_parent->d_inode != dir);
+
+ /* Inode writeback is not safe when the uid or gid are invalid. */
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EOVERFLOW;
+
audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
@@ -3675,7 +3682,8 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
if (error)
return error;
- if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
+ if ((S_ISCHR(mode) || S_ISBLK(mode)) &&
+ !ns_capable(dentry->d_sb->s_user_ns, CAP_MKNOD))
return -EPERM;
if (!dir->i_op->mknod)