diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-11-02 20:41:59 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-11-02 20:41:59 -0500 |
commit | 86a21c79745ca97676cbd47f8608839382cc0448 (patch) | |
tree | 296934f7b383018e655f7e137fa9c5883d9f207b | |
parent | 67d8e04e345eafcb2940066f435815032eec467d (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.h | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.c | 13 |
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 | ||
38 | STATIC struct posix_acl * | 38 | STATIC struct posix_acl * |
39 | xfs_acl_from_disk( | 39 | xfs_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 | ||