[PATCH] xfs: fix heap buffer overflow in xfs_bmbt_to_bmdr

From: Hongling Zeng

Date: Thu Jul 30 2026 - 04:42:54 EST


The xfs_bmbt_to_bmdr() function converts an in-memory btree root to
on-disk form during log recovery. It uses bb_numrecs from the source
to determine memcpy size without validating against the destination
fork capacity.

Current code:
dmxr = xfs_bmdr_maxrecs(dblocklen, 0); // destination capacity
...
dmxr = be16_to_cpu(dblock->bb_numrecs); // overwrite with source value!
memcpy(..., * dmxr); // may overflow destination!

If bb_numrecs is larger than the destination fork capacity,
memcpy writes beyond the fork buffer, causing heap overflow.

Fix by validating bb_numrecs against the destination capacity
before using it for memcpy operations.

Cc: stable@xxxxxxxxxxxxxxx
Fixes: 8ea5682d0711 ("xfs: refactor log recovery item dispatch for pass2 readhead functions")
Signed-off-by: Hongling Zeng <zenghongling@xxxxxxxxxx>
---
fs/xfs/libxfs/xfs_bmap_btree.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 758a4b1ccf5b..3b606bd8aec9 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -151,6 +151,7 @@ xfs_bmbt_to_bmdr(
int dmxr;
xfs_bmbt_key_t *fkp;
__be64 *fpp;
+ int nrecs;
xfs_bmbt_key_t *tkp;
__be64 *tpp;

@@ -167,12 +168,17 @@ xfs_bmbt_to_bmdr(
ASSERT(rblock->bb_level != 0);
dblock->bb_level = rblock->bb_level;
dblock->bb_numrecs = rblock->bb_numrecs;
+
+ /* Validate record count against destination fork capacity */
+ nrecs = be16_to_cpu(rblock->bb_numrecs);
dmxr = xfs_bmdr_maxrecs(dblocklen, 0);
+ if (nrecs > dmxr)
+ return;
+
fkp = xfs_bmbt_key_addr(mp, rblock, 1);
tkp = xfs_bmdr_key_addr(dblock, 1);
fpp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, rblocklen);
- tpp = xfs_bmdr_ptr_addr(dblock, 1, dmxr);
- dmxr = be16_to_cpu(dblock->bb_numrecs);
+ tpp = xfs_bmdr_ptr_addr(dblock, 1, nrecs);
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
}
--
2.25.1