]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
(namespace) vfs: Don't create inodes with a uid or gid unknown to the vfs
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 1 Jul 2016 17:52:06 +0000 (12:52 -0500)
committerLuis Henriques <luis.henriques@canonical.com>
Tue, 8 Nov 2016 16:46:49 +0000 (16:46 +0000)
BugLink: http://bugs.launchpad.net/bugs/1634964
It is expected that filesystems can not represent uids and gids from
outside of their user namespace.  Keep things simple by not even
trying to create filesystem nodes with non-sense uids and gids.

Acked-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
(cherry picked from commit 036d523641c66bef713042894a17f4335f199e49)
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
Acked-by: Tim Gardner <tim.gardner@canonical.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
fs/namei.c

index f3d898ef673bb1c2336fb6bab7fc9c2f541c1f96..f251a018e79f55a6b0cd0be562a9e3a8d16cddbf 100644 (file)
@@ -2608,16 +2608,22 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
  *  1. We can't do it if child already exists (open has special treatment for
  *     this case, but since we are inlined it's OK)
  *  2. We can't do it if dir is read-only (done in permission())
- *  3. We should have write and exec permissions on dir
- *  4. We can't do it if dir is immutable (done in permission())
+ *  3. We can't do it if the fs can't represent the fsuid or fsgid.
+ *  4. We should have write and exec permissions on dir
+ *  5. We can't do it if dir is immutable (done in permission())
  */
 static inline int may_create(struct inode *dir, struct dentry *child)
 {
+       struct user_namespace *s_user_ns;
        audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
        if (child->d_inode)
                return -EEXIST;
        if (IS_DEADDIR(dir))
                return -ENOENT;
+       s_user_ns = dir->i_sb->s_user_ns;
+       if (!kuid_has_mapping(s_user_ns, current_fsuid()) ||
+           !kgid_has_mapping(s_user_ns, current_fsgid()))
+               return -EOVERFLOW;
        return inode_permission(dir, MAY_WRITE | MAY_EXEC);
 }