]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: validate attr entry pointer before field access
authorHongling Zeng <zenghongling@kylinos.cn>
Tue, 28 Jul 2026 07:43:40 +0000 (15:43 +0800)
committerCarlos Maiolino <cem@kernel.org>
Mon, 10 Aug 2026 06:51:30 +0000 (08:51 +0200)
xfs_attr3_leaf_verify_entry() accesses lentry/rentry fields (namelen,
valuelen) before checking if the entry pointer itself is within bounds.
If nameidx is crafted to point near the end of the buffer, these field
accesses can read out-of-bounds before the bounds check at
name_end > buf_end is performed.

Add explicit bounds checks for entry pointers before accessing their
fields. Use offsetof() to check that the start of the flexible array
member (nameval/name) is within bounds, which ensures all preceding
fields are safe to access.

Fixes: c84760659dcf2 ("xfs: check attribute leaf block structure")
Cc: <stable@vger.kernel.org> # v5.5
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/libxfs/xfs_attr_leaf.c

index 86c5c09a5db4f776244a6be0ed5528d3941336b8..b6288395f8533dca792e79fdde6df0c54bf931f6 100644 (file)
@@ -325,6 +325,13 @@ xfs_attr3_leaf_verify_entry(
         */
        if (ent->flags & XFS_ATTR_LOCAL) {
                lentry = xfs_attr3_leaf_name_local(leaf, idx);
+
+               /* Validate lentry pointer is within bounds before field access */
+               if ((char *)lentry >= buf_end)
+                       return __this_address;
+               if ((char *)lentry + offsetof(struct xfs_attr_leaf_name_local, nameval) > buf_end)
+                       return __this_address;
+
                namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
                                be16_to_cpu(lentry->valuelen));
                name_end = (char *)lentry + namesize;
@@ -332,6 +339,13 @@ xfs_attr3_leaf_verify_entry(
                        return __this_address;
        } else {
                rentry = xfs_attr3_leaf_name_remote(leaf, idx);
+
+               /* Validate rentry pointer is within bounds before field access */
+               if ((char *)rentry >= buf_end)
+                       return __this_address;
+               if ((char *)rentry + offsetof(struct xfs_attr_leaf_name_remote, name) > buf_end)
+                       return __this_address;
+
                namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
                name_end = (char *)rentry + namesize;
                if (rentry->namelen == 0)