userns: Pass a userns parameter into posix_acl_to_xattr and posix_acl_from_xattr
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 11 Sep 2012 03:17:44 +0000 (20:17 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 18 Sep 2012 08:01:35 +0000 (01:01 -0700)
 - Pass the user namespace the uid and gid values in the xattr are stored
   in into posix_acl_from_xattr.

 - Pass the user namespace kuid and kgid values should be converted into
   when storing uid and gid values in an xattr in posix_acl_to_xattr.

- Modify all callers of posix_acl_from_xattr and posix_acl_to_xattr to
  pass in &init_user_ns.

In the short term this change is not strictly needed but it makes the
code clearer.  In the longer term this change is necessary to be able to
mount filesystems outside of the initial user namespace that natively
store posix acls in the linux xattr format.

Cc: Theodore Tso <tytso@mit.edu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
17 files changed:
fs/9p/acl.c
fs/btrfs/acl.c
fs/ext2/acl.c
fs/ext3/acl.c
fs/ext4/acl.c
fs/generic_acl.c
fs/gfs2/acl.c
fs/jffs2/acl.c
fs/jfs/acl.c
fs/jfs/xattr.c
fs/nfs/nfs3acl.c
fs/nfsd/vfs.c
fs/ocfs2/acl.c
fs/reiserfs/xattr_acl.c
fs/xattr_acl.c
fs/xfs/xfs_acl.c
include/linux/posix_acl_xattr.h

index 9a1d426307510135444da722883e570fe52410b9..15b6791662011ed9c1269095c4c80d84c461c958 100644 (file)
@@ -37,7 +37,7 @@ static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
                        return ERR_PTR(-ENOMEM);
                size = v9fs_fid_xattr_get(fid, name, value, size);
                if (size > 0) {
-                       acl = posix_acl_from_xattr(value, size);
+                       acl = posix_acl_from_xattr(&init_user_ns, value, size);
                        if (IS_ERR(acl))
                                goto err_out;
                }
@@ -131,7 +131,7 @@ static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl)
        buffer = kmalloc(size, GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;
-       retval = posix_acl_to_xattr(acl, buffer, size);
+       retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        if (retval < 0)
                goto err_free_out;
        switch (type) {
@@ -251,7 +251,7 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -304,7 +304,7 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
                return -EPERM;
        if (value) {
                /* update the cached acl value */
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                else if (acl) {
index 761e2cd8fed16e6046951e50504b8bb9e7acd3e4..0c16e3dbfd5681ea67d4cf2f349cb33083a46d2d 100644 (file)
@@ -61,7 +61,7 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
                size = __btrfs_getxattr(inode, name, value, size);
        }
        if (size > 0) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
        } else if (size == -ENOENT || size == -ENODATA || size == 0) {
                /* FIXME, who returns -ENOENT?  I think nobody */
                acl = NULL;
@@ -91,7 +91,7 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       ret = posix_acl_to_xattr(acl, value, size);
+       ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
        posix_acl_release(acl);
 
        return ret;
@@ -141,7 +141,7 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
                        goto out;
                }
 
-               ret = posix_acl_to_xattr(acl, value, size);
+               ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
                if (ret < 0)
                        goto out;
        }
@@ -169,7 +169,7 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
                return -EOPNOTSUPP;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
 
index 35d6a3cfd9ff3a5c6562adb46fc614595ff4c718..70bb1bccc9573de00f430df71e3bd19982f9c8ad 100644 (file)
@@ -350,7 +350,7 @@ ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -371,7 +371,7 @@ ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                else if (acl) {
index c76832c8d19229d6c868878ca3f7250394f10f72..2cf6a8044c80bbe54fe0859d347b10375ad87c94 100644 (file)
@@ -369,7 +369,7 @@ ext3_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -392,7 +392,7 @@ ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                else if (acl) {
index a5c29bb3b835d7c528d0b9f65ce3436e8b7f9181..42b95fccfb2fdebf73d411cc10250a52418256ed 100644 (file)
@@ -374,7 +374,7 @@ ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -397,7 +397,7 @@ ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                else if (acl) {
index d0dddaceac594888c96388b5ed82f7ab33bc9846..b3f3676796d31a6870a771ed6952977cfc16d448 100644 (file)
@@ -56,7 +56,7 @@ generic_acl_get(struct dentry *dentry, const char *name, void *buffer,
        acl = get_cached_acl(dentry->d_inode, type);
        if (!acl)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -77,7 +77,7 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
        if (!inode_owner_or_capable(inode))
                return -EPERM;
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
        }
index bd4a5892c93ca18791c0032bdb017aeb6357ca98..f850020ad906a68cc715602e024f1a9bd18c1b88 100644 (file)
@@ -63,7 +63,7 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
        if (len == 0)
                return NULL;
 
-       acl = posix_acl_from_xattr(data, len);
+       acl = posix_acl_from_xattr(&init_user_ns, data, len);
        kfree(data);
        return acl;
 }
@@ -88,13 +88,13 @@ static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)
        const char *name = gfs2_acl_name(type);
 
        BUG_ON(name == NULL);
-       len = posix_acl_to_xattr(acl, NULL, 0);
+       len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
        if (len == 0)
                return 0;
        data = kmalloc(len, GFP_NOFS);
        if (data == NULL)
                return -ENOMEM;
-       error = posix_acl_to_xattr(acl, data, len);
+       error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
        if (error < 0)
                goto out;
        error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
@@ -166,12 +166,12 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
        if (error)
                return error;
 
-       len = posix_acl_to_xattr(acl, NULL, 0);
+       len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
        data = kmalloc(len, GFP_NOFS);
        error = -ENOMEM;
        if (data == NULL)
                goto out;
-       posix_acl_to_xattr(acl, data, len);
+       posix_acl_to_xattr(&init_user_ns, acl, data, len);
        error = gfs2_xattr_acl_chmod(ip, attr, data);
        kfree(data);
        set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
@@ -212,7 +212,7 @@ static int gfs2_xattr_system_get(struct dentry *dentry, const char *name,
        if (acl == NULL)
                return -ENODATA;
 
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
@@ -245,7 +245,7 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
        if (!value)
                goto set_acl;
 
-       acl = posix_acl_from_xattr(value, size);
+       acl = posix_acl_from_xattr(&init_user_ns, value, size);
        if (!acl) {
                /*
                 * acl_set_file(3) may request that we set default ACLs with
index 922f146e42354fb34d7ed68f225901b44e5db77d..42e4edc17a903feed22f6c08110daefe215fd9cc 100644 (file)
@@ -363,7 +363,7 @@ static int jffs2_acl_getxattr(struct dentry *dentry, const char *name,
                return PTR_ERR(acl);
        if (!acl)
                return -ENODATA;
-       rc = posix_acl_to_xattr(acl, buffer, size);
+       rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return rc;
@@ -381,7 +381,7 @@ static int jffs2_acl_setxattr(struct dentry *dentry, const char *name,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                if (acl) {
index 45559dc3ea2f59297f57c523a8eac2b3f40c06c6..d254d6d3599565fbca59621cf840d105d9cd4971 100644 (file)
@@ -64,7 +64,7 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type)
                else
                        acl = ERR_PTR(size);
        } else {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
        }
        kfree(value);
        if (!IS_ERR(acl))
@@ -100,7 +100,7 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
                value = kmalloc(size, GFP_KERNEL);
                if (!value)
                        return -ENOMEM;
-               rc = posix_acl_to_xattr(acl, value, size);
+               rc = posix_acl_to_xattr(&init_user_ns, acl, value, size);
                if (rc < 0)
                        goto out;
        }
index 26683e15b3ac9f23991110687023e0f6e3bb0db0..42d67f9757bf641d316b07e78a3fb1a698f76409 100644 (file)
@@ -685,7 +685,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
         * POSIX_ACL_XATTR_ACCESS is tied to i_mode
         */
        if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
-               acl = posix_acl_from_xattr(value, value_len);
+               acl = posix_acl_from_xattr(&init_user_ns, value, value_len);
                if (IS_ERR(acl)) {
                        rc = PTR_ERR(acl);
                        printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
@@ -710,7 +710,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
 
                return 0;
        } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
-               acl = posix_acl_from_xattr(value, value_len);
+               acl = posix_acl_from_xattr(&init_user_ns, value, value_len);
                if (IS_ERR(acl)) {
                        rc = PTR_ERR(acl);
                        printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
index e4498dc351a834fcc35722645abfa50eaefa80fd..4a1aafba6a20030532ba589ac9db021b10c21ceb 100644 (file)
@@ -70,7 +70,7 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
                if (type == ACL_TYPE_ACCESS && acl->a_count == 0)
                        error = -ENODATA;
                else
-                       error = posix_acl_to_xattr(acl, buffer, size);
+                       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
                posix_acl_release(acl);
        } else
                error = -ENODATA;
@@ -92,7 +92,7 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
        else
                return -EOPNOTSUPP;
 
-       acl = posix_acl_from_xattr(value, size);
+       acl = posix_acl_from_xattr(&init_user_ns, value, size);
        if (IS_ERR(acl))
                return PTR_ERR(acl);
        error = nfs3_proc_setacl(inode, type, acl);
index a9269f142cc481ec451c681397f520c1a1cb97f7..3f67b8e122515302709e606ef38881ba01aae581 100644 (file)
@@ -480,7 +480,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
        if (buf == NULL)
                goto out;
 
-       len = posix_acl_to_xattr(pacl, buf, buflen);
+       len = posix_acl_to_xattr(&init_user_ns, pacl, buf, buflen);
        if (len < 0) {
                error = len;
                goto out;
@@ -549,7 +549,7 @@ _get_posix_acl(struct dentry *dentry, char *key)
        if (buflen <= 0)
                return ERR_PTR(buflen);
 
-       pacl = posix_acl_from_xattr(buf, buflen);
+       pacl = posix_acl_from_xattr(&init_user_ns, buf, buflen);
        kfree(buf);
        return pacl;
 }
@@ -2264,7 +2264,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
        if (size < 0)
                return ERR_PTR(size);
 
-       acl = posix_acl_from_xattr(value, size);
+       acl = posix_acl_from_xattr(&init_user_ns, value, size);
        kfree(value);
        return acl;
 }
@@ -2297,7 +2297,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
                value = kmalloc(size, GFP_KERNEL);
                if (!value)
                        return -ENOMEM;
-               error = posix_acl_to_xattr(acl, value, size);
+               error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
                if (error < 0)
                        goto getout;
                size = error;
index a7219075b4deddcd7881a9b3a5c1586f731d36f2..260b16281fc349b216444c4c56b04acf8e04996c 100644 (file)
@@ -452,7 +452,7 @@ static int ocfs2_xattr_get_acl(struct dentry *dentry, const char *name,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       ret = posix_acl_to_xattr(acl, buffer, size);
+       ret = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return ret;
@@ -475,7 +475,7 @@ static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
                else if (acl) {
index 44474f9b990db532124d29460983858465186e33..87d6911c659df1bd9062cbf8bee8106e8d827da9 100644 (file)
@@ -30,7 +30,7 @@ posix_acl_set(struct dentry *dentry, const char *name, const void *value,
                return -EPERM;
 
        if (value) {
-               acl = posix_acl_from_xattr(value, size);
+               acl = posix_acl_from_xattr(&init_user_ns, value, size);
                if (IS_ERR(acl)) {
                        return PTR_ERR(acl);
                } else if (acl) {
@@ -77,7 +77,7 @@ posix_acl_get(struct dentry *dentry, const char *name, void *buffer,
                return PTR_ERR(acl);
        if (acl == NULL)
                return -ENODATA;
-       error = posix_acl_to_xattr(acl, buffer, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
        posix_acl_release(acl);
 
        return error;
index bf472ca1b3485ed661d0fdd567d4f7710ecfb901..11efd830b5f5e4c078279846f335d1560eb35487 100644 (file)
@@ -73,7 +73,8 @@ void posix_acl_fix_xattr_to_user(void *value, size_t size)
  * Convert from extended attribute to in-memory representation.
  */
 struct posix_acl *
-posix_acl_from_xattr(const void *value, size_t size)
+posix_acl_from_xattr(struct user_namespace *user_ns,
+                    const void *value, size_t size)
 {
        posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
        posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
@@ -112,14 +113,14 @@ posix_acl_from_xattr(const void *value, size_t size)
 
                        case ACL_USER:
                                acl_e->e_uid =
-                                       make_kuid(&init_user_ns,
+                                       make_kuid(user_ns,
                                                  le32_to_cpu(entry->e_id));
                                if (!uid_valid(acl_e->e_uid))
                                        goto fail;
                                break;
                        case ACL_GROUP:
                                acl_e->e_gid =
-                                       make_kgid(&init_user_ns,
+                                       make_kgid(user_ns,
                                                  le32_to_cpu(entry->e_id));
                                if (!gid_valid(acl_e->e_gid))
                                        goto fail;
@@ -141,7 +142,8 @@ EXPORT_SYMBOL (posix_acl_from_xattr);
  * Convert from in-memory to extended attribute representation.
  */
 int
-posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size)
+posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
+                  void *buffer, size_t size)
 {
        posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
        posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
@@ -162,11 +164,11 @@ posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size)
                switch(acl_e->e_tag) {
                case ACL_USER:
                        ext_entry->e_id =
-                               cpu_to_le32(from_kuid(&init_user_ns, acl_e->e_uid));
+                               cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
                        break;
                case ACL_GROUP:
                        ext_entry->e_id =
-                               cpu_to_le32(from_kgid(&init_user_ns, acl_e->e_gid));
+                               cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
                        break;
                default:
                        ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
index ac702a6eab9b05f6e1e4b9e3dde769a06262f84b..1d32f1d5276339e96b0034e13050eaeb39dba653 100644 (file)
@@ -337,7 +337,7 @@ xfs_xattr_acl_get(struct dentry *dentry, const char *name,
        if (acl == NULL)
                return -ENODATA;
 
-       error = posix_acl_to_xattr(acl, value, size);
+       error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
        posix_acl_release(acl);
 
        return error;
@@ -361,7 +361,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
        if (!value)
                goto set_acl;
 
-       acl = posix_acl_from_xattr(value, size);
+       acl = posix_acl_from_xattr(&init_user_ns, value, size);
        if (!acl) {
                /*
                 * acl_set_file(3) may request that we set default ACLs with
index 8bd5fcf0691630936193549898171022db0dcd23..ad93ad0f1db0b0afe072d587a6fd1507f2e35d84 100644 (file)
@@ -64,7 +64,9 @@ static inline void posix_acl_fix_xattr_to_user(void *value, size_t size)
 }
 #endif
 
-struct posix_acl *posix_acl_from_xattr(const void *value, size_t size);
-int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
+struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, 
+                                      const void *value, size_t size);
+int posix_acl_to_xattr(struct user_namespace *user_ns,
+                      const struct posix_acl *acl, void *buffer, size_t size);
 
 #endif /* _POSIX_ACL_XATTR_H */