diff options
author | Dwight Engen <dwight.engen@oracle.com> | 2013-08-15 22:07:59 +0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-08-15 23:18:31 +0400 |
commit | 288bbe0eeb3da7238482ca586c6fb029801336be (patch) | |
tree | a5af810265278672af29a90ae578ee7aa66a6974 | |
parent | c5eeb7ec3e1bb9884e97066bc293792ab57fb4ab (diff) | |
download | linux-288bbe0eeb3da7238482ca586c6fb029801336be.tar.xz |
xfs: convert kuid_t to/from uid_t in ACLs
Change permission check for setting ACL to use inode_owner_or_capable()
which will additionally allow a CAP_FOWNER user in a user namespace to
be able to set an ACL on an inode covered by the user namespace mapping.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r-- | fs/xfs/xfs_acl.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 2f77db865ad9..69518960b2ba 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -70,14 +70,15 @@ xfs_acl_from_disk( switch (acl_e->e_tag) { case ACL_USER: + acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); + break; case ACL_GROUP: - acl_e->e_id = be32_to_cpu(ace->ae_id); + acl_e->e_gid = xfs_gid_to_kgid(be32_to_cpu(ace->ae_id)); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER: - acl_e->e_id = ACL_UNDEFINED_ID; break; default: goto fail; @@ -103,7 +104,18 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) acl_e = &acl->a_entries[i]; ace->ae_tag = cpu_to_be32(acl_e->e_tag); - ace->ae_id = cpu_to_be32(acl_e->e_id); + switch (acl_e->e_tag) { + case ACL_USER: + ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(acl_e->e_uid)); + break; + case ACL_GROUP: + ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(acl_e->e_gid)); + break; + default: + ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID); + break; + } + ace->ae_perm = cpu_to_be16(acl_e->e_perm); } } @@ -362,7 +374,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, return -EINVAL; if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) return value ? -EACCES : 0; - if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER)) + if (!inode_owner_or_capable(inode)) return -EPERM; if (!value) |