summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHongling Zeng <zenghongling@kylinos.cn>2026-07-28 15:43:40 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-08-27 14:32:05 +0200
commit98a42bb9d60d42898c3494de351a1bf508348cde (patch)
treee9488f7a5ccb07d2f25f64706d100680c7e774f8
parent40b741de4a8277a58645e5f1ce98e70e751ca6b4 (diff)
xfs: validate attr entry pointer before field access
commit b7eea80be25f3334f131d52982b3131aba77b97d upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 7c307025cfcb..62079d2e630d 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -268,6 +268,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;
@@ -275,6 +282,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)