xfs
[Top] [All Lists]

[PATCH 1/4] xfs: Validate the length of on-disk ACLs

To: Brian Foster <bfoster@xxxxxxxxxx>, xfs@xxxxxxxxxxx
Subject: [PATCH 1/4] xfs: Validate the length of on-disk ACLs
From: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
Date: Sat, 24 Oct 2015 23:16:06 +0200
Cc: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1445721369-25679-1-git-send-email-agruenba@xxxxxxxxxx>
References: <1445721369-25679-1-git-send-email-agruenba@xxxxxxxxxx>
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@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_format.h |  8 ++++++--
 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 9590a06..0e62682 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -1487,9 +1487,13 @@ struct xfs_acl {
                                                sizeof(struct xfs_acl_entry) \
                : 25)
 
-#define XFS_ACL_MAX_SIZE(mp) \
+#define XFS_ACL_SIZE(cnt) \
        (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 */
 #define SGI_ACL_FILE           "SGI_ACL_FILE"
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4b64167..763e365 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;
 
-- 
2.5.0

<Prev in Thread] Current Thread [Next in Thread>