]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
UBUNTU: SAUCE: overlayfs: Skip permission checking for trusted.overlayfs.* xattrs
authorSeth Forshee <seth.forshee@canonical.com>
Tue, 19 Jan 2016 19:12:02 +0000 (13:12 -0600)
committerTim Gardner <tim.gardner@canonical.com>
Mon, 20 Feb 2017 03:57:58 +0000 (20:57 -0700)
The original mounter had CAP_SYS_ADMIN in the user namespace
where the mount happened, and the vfs has validated that the user
has permission to do the requested operation. This is sufficient
for allowing the kernel to write these specific xattrs, so we can
bypass the permission checks for these xattrs.

To support this, export __vfs_setxattr_noperm and add an similar
__vfs_removexattr_noperm which is also exported. Use these when
setting or removing trusted.overlayfs.* xattrs.

BugLink: http://bugs.launchpad.net/bugs/1531747
BugLink: http://bugs.launchpad.net/bugs/1534961
BugLink: http://bugs.launchpad.net/bugs/1535150
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
fs/overlayfs/overlayfs.h
fs/xattr.c
include/linux/xattr.h

index 8af450b0e57a2d826f289d87a1ace6db2d8e7d73..f14fb7b56b094ca49845652dbb674569435c7863 100644 (file)
@@ -89,7 +89,13 @@ static inline int ovl_do_symlink(struct inode *dir, struct dentry *dentry,
 static inline int ovl_do_setxattr(struct dentry *dentry, const char *name,
                                  const void *value, size_t size, int flags)
 {
-       int err = vfs_setxattr(dentry, name, value, size, flags);
+       struct inode *inode = dentry->d_inode;
+       int err;
+
+       inode_lock(inode);
+       err = __vfs_setxattr_noperm(dentry, name, value, size, flags);
+       inode_unlock(inode);
+
        pr_debug("setxattr(%pd2, \"%s\", \"%*s\", 0x%x) = %i\n",
                 dentry, name, (int) size, (char *) value, flags, err);
        return err;
@@ -97,7 +103,13 @@ static inline int ovl_do_setxattr(struct dentry *dentry, const char *name,
 
 static inline int ovl_do_removexattr(struct dentry *dentry, const char *name)
 {
-       int err = vfs_removexattr(dentry, name);
+       struct inode *inode = dentry->d_inode;
+       int err;
+
+       inode_lock(inode);
+       err = __vfs_removexattr_noperm(dentry, name);
+       inode_unlock(inode);
+
        pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
        return err;
 }
index 88910fe4a8ba0b2d7bcb1f3aba78c2a3572ab747..d09bb27e0ae6f63ff923ca442df8878f56b4fadd 100644 (file)
@@ -202,6 +202,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
 
        return error;
 }
+EXPORT_SYMBOL_GPL(__vfs_setxattr_noperm);
 
 
 int
@@ -380,6 +381,33 @@ __vfs_removexattr(struct dentry *dentry, const char *name)
 }
 EXPORT_SYMBOL(__vfs_removexattr);
 
+/**
+ *  __vfs_removexattr_noperm - perform removexattr operation without
+ *  performing permission checks.
+ *
+ *  @dentry - object to perform setxattr on
+ *  @name - xattr name to set
+ *
+ *  returns the result of the internal setxattr or setsecurity operations.
+ *
+ *  This function requires the caller to lock the inode's i_mutex before it
+ *  is executed. It also assumes that the caller will make the appropriate
+ *  permission checks.
+ */
+int
+__vfs_removexattr_noperm(struct dentry *dentry, const char *name)
+{
+       int error;
+
+       error =__vfs_removexattr(dentry, name);
+       if (!error) {
+               fsnotify_xattr(dentry);
+               evm_inode_post_removexattr(dentry, name);
+       }
+       return error;
+}
+EXPORT_SYMBOL_GPL(__vfs_removexattr_noperm);
+
 int
 vfs_removexattr(struct dentry *dentry, const char *name)
 {
@@ -395,12 +423,7 @@ vfs_removexattr(struct dentry *dentry, const char *name)
        if (error)
                goto out;
 
-       error = __vfs_removexattr(dentry, name);
-
-       if (!error) {
-               fsnotify_xattr(dentry);
-               evm_inode_post_removexattr(dentry, name);
-       }
+       error = __vfs_removexattr_noperm(dentry, name);
 
 out:
        inode_unlock(inode);
index e77605a0c8da34ec14807fe912d1a5ed45ad999d..6fb2dfcaf99ab1199be42312c7c9fb314f137e10 100644 (file)
@@ -53,6 +53,7 @@ int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *,
 int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
 int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int __vfs_removexattr(struct dentry *, const char *);
+int __vfs_removexattr_noperm(struct dentry *dentry, const char *name);
 int vfs_removexattr(struct dentry *, const char *);
 
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);