Skip to content

Commit

Permalink
userns: Pass a userns parameter into posix_acl_to_xattr and posix_acl…
Browse files Browse the repository at this point in the history
…_from_xattr

 - 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 <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andreas Dilger <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
  • Loading branch information
ebiederm committed Sep 18, 2012
1 parent 2f6f065 commit 5f3a4a2
Show file tree
Hide file tree
Showing 17 changed files with 53 additions and 49 deletions.
8 changes: 4 additions & 4 deletions fs/9p/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions fs/btrfs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions fs/ext2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions fs/ext3/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions fs/ext4/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions fs/generic_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
14 changes: 7 additions & 7 deletions fs/gfs2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions fs/jffs2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions fs/jfs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions fs/jfs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/nfs3acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions fs/ocfs2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions fs/reiserfs/xattr_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 8 additions & 6 deletions fs/xattr_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down
Loading

0 comments on commit 5f3a4a2

Please sign in to comment.