From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Aldo Ariel Panzardo <qwe.aldo@gmail.com>,
"Darrick J. Wong" <djwong@kernel.org>,
Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.15.y] xfs: bound inode fork length against the fork size during log recovery
Date: Thu, 5 Nov 2026 10:02:33 -0500 [thread overview]
Message-ID: <20261105150122.1662584-1-sashal@kernel.org> (raw)
In-Reply-To: <2026110424-cure-criteria-18e5@gregkh>
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
[ Upstream commit 9232301894a06e664d8de2da97175cf98419bd16 ]
xlog_recover_inode_commit_pass2() copies an inode log item's data/attr
fork region into the inode buffer using the on-log region length without
bounding it against the fork capacity, e.g.:
len = item->ri_buf[2].iov_len;
memcpy(XFS_DFORK_DPTR(dip), src, len);
The only guard is an ASSERT, which is a no-op on production kernels
(CONFIG_XFS_DEBUG off), and xfs_dinode_verify() runs only after the copy.
A crafted image with a dirty log can therefore drive a heap out-of-bounds
write at mount time. The XFS_ILOG_DBROOT sibling already passes
XFS_DFORK_DSIZE as a bound; the DDATA/DEXT and ADATA/AEXT memcpy paths
did not.
Bound each logged fork region against the destination fork size before
copying it, and reject the log item with -EFSCORRUPTED when it does not
fit. Because the recovered inode is only verified after the fork data has
been copied in, the checks are done up front, before any memcpy into the
on-disk inode.
Fixes: 658fa68b6f34 ("xfs: refactor log recovery inode item dispatch for pass2 commit functions")
Cc: stable@vger.kernel.org # v5.8
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ sashal: Changed two iov_len accesses to i_len to match struct xfs_log_iovec recovery buffers. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_inode_item_recover.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
index 239dd2e3384ec..2e82ee4b404b5 100644
--- a/fs/xfs/xfs_inode_item_recover.c
+++ b/fs/xfs/xfs_inode_item_recover.c
@@ -403,6 +403,25 @@ xlog_recover_inode_commit_pass2(
ASSERT(!(fields & XFS_ILOG_DFORK) ||
(len == in_f->ilf_dsize));
+ /*
+ * The recovered inode is verified only after the fork data has been
+ * copied into it, so bound each logged fork region against the size of
+ * its fork now, before the memcpy below can overrun the on-disk inode.
+ * The DBROOT/ABROOT cases already bound their copies against the fork
+ * size.
+ */
+ if ((fields & (XFS_ILOG_DDATA | XFS_ILOG_DEXT)) &&
+ item->ri_buf[2].i_len > XFS_DFORK_DSIZE(dip, mp)) {
+ error = -EFSCORRUPTED;
+ goto out_release;
+ }
+ if ((fields & (XFS_ILOG_ADATA | XFS_ILOG_AEXT)) &&
+ item->ri_buf[(fields & XFS_ILOG_DFORK) ? 3 : 2].i_len >
+ XFS_DFORK_ASIZE(dip, mp)) {
+ error = -EFSCORRUPTED;
+ goto out_release;
+ }
+
switch (fields & XFS_ILOG_DFORK) {
case XFS_ILOG_DDATA:
case XFS_ILOG_DEXT:
@@ -442,7 +461,6 @@ xlog_recover_inode_commit_pass2(
case XFS_ILOG_ADATA:
case XFS_ILOG_AEXT:
dest = XFS_DFORK_APTR(dip);
- ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
memcpy(dest, src, len);
break;
--
2.53.0
prev parent reply other threads:[~2026-11-05 15:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 17:41 FAILED: patch "[PATCH] xfs: bound inode fork length against the fork size during log" failed to apply to 5.15-stable tree gregkh
2026-11-05 15:02 ` Sasha Levin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261105150122.1662584-1-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=cem@kernel.org \
--cc=djwong@kernel.org \
--cc=qwe.aldo@gmail.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.