aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2015-11-02 20:41:59 -0500
committerDave Chinner <david@fromorbit.com>2015-11-02 20:41:59 -0500
commit86a21c79745ca97676cbd47f8608839382cc0448 (patch)
tree296934f7b383018e655f7e137fa9c5883d9f207b
parent67d8e04e345eafcb2940066f435815032eec467d (diff)
xfs: Validate the length of on-disk ACLs
In xfs_acl_from_disk, instead of trusting that xfs_acl.acl_cnt is correct, make sure that the length of the attributes is correct as well. Also, turn the aclp parameter into a const pointer. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_format.h8
-rw-r--r--fs/xfs/xfs_acl.c13
2 files changed, 14 insertions, 7 deletions
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 9590a069e556..0e62682e7019 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -1487,9 +1487,13 @@ struct xfs_acl {
1487 sizeof(struct xfs_acl_entry) \ 1487 sizeof(struct xfs_acl_entry) \
1488 : 25) 1488 : 25)
1489 1489
1490#define XFS_ACL_MAX_SIZE(mp) \ 1490#define XFS_ACL_SIZE(cnt) \
1491 (sizeof(struct xfs_acl) + \ 1491 (sizeof(struct xfs_acl) + \
1492 sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp))) 1492 sizeof(struct xfs_acl_entry) * cnt)
1493
1494#define XFS_ACL_MAX_SIZE(mp) \
1495 XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp)))
1496
1493 1497
1494/* On-disk XFS extended attribute names */ 1498/* On-disk XFS extended attribute names */
1495#define SGI_ACL_FILE "SGI_ACL_FILE" 1499#define SGI_ACL_FILE "SGI_ACL_FILE"
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4b641676f258..763e36560681 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -37,16 +37,19 @@
37 37
38STATIC struct posix_acl * 38STATIC struct posix_acl *
39xfs_acl_from_disk( 39xfs_acl_from_disk(
40 struct xfs_acl *aclp, 40 const struct xfs_acl *aclp,
41 int max_entries) 41 int len,
42 int max_entries)
42{ 43{
43 struct posix_acl_entry *acl_e; 44 struct posix_acl_entry *acl_e;
44 struct posix_acl *acl; 45 struct posix_acl *acl;
45 struct xfs_acl_entry *ace; 46 const struct xfs_acl_entry *ace;
46 unsigned int count, i; 47 unsigned int count, i;
47 48
49 if (len < sizeof(*aclp))
50 return ERR_PTR(-EFSCORRUPTED);
48 count = be32_to_cpu(aclp->acl_cnt); 51 count = be32_to_cpu(aclp->acl_cnt);
49 if (count > max_entries) 52 if (count > max_entries || XFS_ACL_SIZE(count) != len)
50 return ERR_PTR(-EFSCORRUPTED); 53 return ERR_PTR(-EFSCORRUPTED);
51 54
52 acl = posix_acl_alloc(count, GFP_KERNEL); 55 acl = posix_acl_alloc(count, GFP_KERNEL);
@@ -163,7 +166,7 @@ xfs_get_acl(struct inode *inode, int type)
163 goto out; 166 goto out;
164 } 167 }
165 168
166 acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); 169 acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount));
167 if (IS_ERR(acl)) 170 if (IS_ERR(acl))
168 goto out; 171 goto out;
169 172