mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
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>
This commit is contained in:
parent
67d8e04e34
commit
86a21c7974
2 changed files with 14 additions and 7 deletions
|
@ -1487,9 +1487,13 @@ struct xfs_acl {
|
||||||
sizeof(struct xfs_acl_entry) \
|
sizeof(struct xfs_acl_entry) \
|
||||||
: 25)
|
: 25)
|
||||||
|
|
||||||
#define XFS_ACL_MAX_SIZE(mp) \
|
#define XFS_ACL_SIZE(cnt) \
|
||||||
(sizeof(struct xfs_acl) + \
|
(sizeof(struct xfs_acl) + \
|
||||||
sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
|
sizeof(struct xfs_acl_entry) * cnt)
|
||||||
|
|
||||||
|
#define XFS_ACL_MAX_SIZE(mp) \
|
||||||
|
XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp)))
|
||||||
|
|
||||||
|
|
||||||
/* On-disk XFS extended attribute names */
|
/* On-disk XFS extended attribute names */
|
||||||
#define SGI_ACL_FILE "SGI_ACL_FILE"
|
#define SGI_ACL_FILE "SGI_ACL_FILE"
|
||||||
|
|
|
@ -37,16 +37,19 @@
|
||||||
|
|
||||||
STATIC struct posix_acl *
|
STATIC struct posix_acl *
|
||||||
xfs_acl_from_disk(
|
xfs_acl_from_disk(
|
||||||
struct xfs_acl *aclp,
|
const struct xfs_acl *aclp,
|
||||||
|
int len,
|
||||||
int max_entries)
|
int max_entries)
|
||||||
{
|
{
|
||||||
struct posix_acl_entry *acl_e;
|
struct posix_acl_entry *acl_e;
|
||||||
struct posix_acl *acl;
|
struct posix_acl *acl;
|
||||||
struct xfs_acl_entry *ace;
|
const struct xfs_acl_entry *ace;
|
||||||
unsigned int count, i;
|
unsigned int count, i;
|
||||||
|
|
||||||
|
if (len < sizeof(*aclp))
|
||||||
|
return ERR_PTR(-EFSCORRUPTED);
|
||||||
count = be32_to_cpu(aclp->acl_cnt);
|
count = be32_to_cpu(aclp->acl_cnt);
|
||||||
if (count > max_entries)
|
if (count > max_entries || XFS_ACL_SIZE(count) != len)
|
||||||
return ERR_PTR(-EFSCORRUPTED);
|
return ERR_PTR(-EFSCORRUPTED);
|
||||||
|
|
||||||
acl = posix_acl_alloc(count, GFP_KERNEL);
|
acl = posix_acl_alloc(count, GFP_KERNEL);
|
||||||
|
@ -163,7 +166,7 @@ xfs_get_acl(struct inode *inode, int type)
|
||||||
goto out;
|
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))
|
if (IS_ERR(acl))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue