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 | ||
