]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: fix a sloppy memory handling bug in xfs_iroot_realloc
authorDarrick J. Wong <djwong@kernel.org>
Fri, 30 Aug 2024 22:37:20 +0000 (15:37 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Sun, 1 Sep 2024 15:58:20 +0000 (08:58 -0700)
While refactoring code, I noticed that when xfs_iroot_realloc tries to
shrink a bmbt root block, it allocates a smaller new block and then
copies "records" and pointers to the new block.  However, bmbt root
blocks cannot ever be leaves, which means that it's not technically
correct to copy records.  We /should/ be copying keys.

Note that this has never resulted in actual memory corruption because
sizeof(bmbt_rec) == (sizeof(bmbt_key) + sizeof(bmbt_ptr)).  However,
this will no longer be true when we start adding realtime rmap stuff,
so fix this now.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_inode_fork.c

index 9d11ae01590919740a2d59c84c8e5094be6eb041..6223823009049bfd31bccc6246e0b0d8367f9405 100644 (file)
@@ -463,15 +463,15 @@ xfs_iroot_realloc(
        }
 
        /*
-        * Only copy the records and pointers if there are any.
+        * Only copy the keys and pointers if there are any.
         */
        if (new_max > 0) {
                /*
-                * First copy the records.
+                * First copy the keys.
                 */
-               op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
-               np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
-               memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
+               op = (char *)XFS_BMBT_KEY_ADDR(mp, ifp->if_broot, 1);
+               np = (char *)XFS_BMBT_KEY_ADDR(mp, new_broot, 1);
+               memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t));
 
                /*
                 * Then copy the pointers.