Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86a21c79 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Dave Chinner
Browse files

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: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 67d8e04e
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -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"
+8 −5
Original line number Original line Diff line number Diff line
@@ -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;