diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-11-03 12:41:59 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-11-03 12:41:59 +1100 |
commit | 86a21c79745ca97676cbd47f8608839382cc0448 (patch) | |
tree | 296934f7b383018e655f7e137fa9c5883d9f207b /fs/xfs/xfs_acl.c | |
parent | 67d8e04e345eafcb2940066f435815032eec467d (diff) | |
download | lwn-86a21c79745ca97676cbd47f8608839382cc0448.tar.gz lwn-86a21c79745ca97676cbd47f8608839382cc0448.zip |
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>
Diffstat (limited to 'fs/xfs/xfs_acl.c')
-rw-r--r-- | fs/xfs/xfs_acl.c | 13 |
1 files changed, 8 insertions, 5 deletions
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 @@ STATIC struct posix_acl * xfs_acl_from_disk( - struct xfs_acl *aclp, - int max_entries) + const struct xfs_acl *aclp, + int len, + int max_entries) { struct posix_acl_entry *acl_e; struct posix_acl *acl; - struct xfs_acl_entry *ace; + const struct xfs_acl_entry *ace; unsigned int count, i; + if (len < sizeof(*aclp)) + return ERR_PTR(-EFSCORRUPTED); count = be32_to_cpu(aclp->acl_cnt); - if (count > max_entries) + if (count > max_entries || XFS_ACL_SIZE(count) != len) return ERR_PTR(-EFSCORRUPTED); acl = posix_acl_alloc(count, GFP_KERNEL); @@ -163,7 +166,7 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount)); if (IS_ERR(acl)) goto out; |