linux/fs/xfs/scrub
Darrick J. Wong 678e1cc2f4 xfs: fix out of bounds memory read error in symlink repair
xfs/286 produced this report on my test fleet:

 ==================================================================
 BUG: KFENCE: out-of-bounds read in memcpy_orig+0x54/0x110

 Out-of-bounds read at 0xffff88843fe9e038 (184B right of kfence-#184):
  memcpy_orig+0x54/0x110
  xrep_symlink_salvage_inline+0xb3/0xf0 [xfs]
  xrep_symlink_salvage+0x100/0x110 [xfs]
  xrep_symlink+0x2e/0x80 [xfs]
  xrep_attempt+0x61/0x1f0 [xfs]
  xfs_scrub_metadata+0x34f/0x5c0 [xfs]
  xfs_ioc_scrubv_metadata+0x387/0x560 [xfs]
  xfs_file_ioctl+0xe23/0x10e0 [xfs]
  __x64_sys_ioctl+0x76/0xc0
  do_syscall_64+0x4e/0x1e0
  entry_SYSCALL_64_after_hwframe+0x4b/0x53

 kfence-#184: 0xffff88843fe9df80-0xffff88843fe9dfea, size=107, cache=kmalloc-128

 allocated by task 3470 on cpu 1 at 263329.131592s (192823.508886s ago):
  xfs_init_local_fork+0x79/0xe0 [xfs]
  xfs_iformat_local+0xa4/0x170 [xfs]
  xfs_iformat_data_fork+0x148/0x180 [xfs]
  xfs_inode_from_disk+0x2cd/0x480 [xfs]
  xfs_iget+0x450/0xd60 [xfs]
  xfs_bulkstat_one_int+0x6b/0x510 [xfs]
  xfs_bulkstat_iwalk+0x1e/0x30 [xfs]
  xfs_iwalk_ag_recs+0xdf/0x150 [xfs]
  xfs_iwalk_run_callbacks+0xb9/0x190 [xfs]
  xfs_iwalk_ag+0x1dc/0x2f0 [xfs]
  xfs_iwalk_args.constprop.0+0x6a/0x120 [xfs]
  xfs_iwalk+0xa4/0xd0 [xfs]
  xfs_bulkstat+0xfa/0x170 [xfs]
  xfs_ioc_fsbulkstat.isra.0+0x13a/0x230 [xfs]
  xfs_file_ioctl+0xbf2/0x10e0 [xfs]
  __x64_sys_ioctl+0x76/0xc0
  do_syscall_64+0x4e/0x1e0
  entry_SYSCALL_64_after_hwframe+0x4b/0x53

 CPU: 1 UID: 0 PID: 1300113 Comm: xfs_scrub Not tainted 6.18.0-rc4-djwx #rc4 PREEMPT(lazy)  3d744dd94e92690f00a04398d2bd8631dcef1954
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-4.module+el8.8.0+21164+ed375313 04/01/2014
 ==================================================================

On further analysis, I realized that the second parameter to min() is
not correct.  xfs_ifork::if_bytes is the size of the xfs_ifork::if_data
buffer.  if_bytes can be smaller than the data fork size because:

(a) the forkoff code tries to keep the data area as large as possible
(b) for symbolic links, if_bytes is the ondisk file size + 1
(c) forkoff is always a multiple of 8.

Case in point: for a single-byte symlink target, forkoff will be
8 but the buffer will only be 2 bytes long.

In other words, the logic here is wrong and we walk off the end of the
incore buffer.  Fix that.

Cc: stable@vger.kernel.org # v6.10
Fixes: 2651923d8d ("xfs: online repair of symbolic links")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
History 2025-11-20 11:06:24 +01:00
..
agb_bitmap.c xfs: move the per-AG datatype bitmaps to separate files 2023-12-15 10:03:30 -08:00
agb_bitmap.h xfs: create agblock bitmap helper to count the number of set regions 2024-02-22 12:43:37 -08:00
agheader.c xfs: define the zoned on-disk format 2025-03-03 08:16:45 -07:00
agheader_repair.c xfs: fix CoW forks for realtime files 2024-12-23 13:06:17 -08:00
agino_bitmap.h xfs: repair AGI unlinked inode bucket lists 2024-04-15 14:58:58 -07:00
alloc.c xfs: add a generic group pointer to the btree cursor 2024-11-05 13:38:29 -08:00
alloc_repair.c xfs: add a realtime flag to the rmap update log redo items 2024-12-23 13:06:04 -08:00
attr.c xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
attr.h xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
attr_repair.c xfs: exchange-range for repairs is no longer dynamic 2024-04-23 16:55:19 -07:00
attr_repair.h xfs: actually rebuild the parent pointer xattrs 2024-04-23 16:55:15 -07:00
bitmap.c xfs: fix sparse warnings about unused interval tree functions 2024-04-22 12:51:43 +05:30
bitmap.h xfs: create agblock bitmap helper to count the number of set regions 2024-02-22 12:43:37 -08:00
bmap.c xfs: allow COW forks on zoned file systems in xchk_bmap 2025-03-03 08:17:08 -07:00
bmap_repair.c xfs: check for shared rt extents when rebuilding rt file's data fork 2024-12-23 13:06:16 -08:00
btree.c xfs: refactor xfs_btree_diff_two_ptrs() to take advantage of cmp_int() 2025-07-24 17:30:13 +02:00
btree.h overflow: Add struct_size_t() helper 2023-05-26 13:52:19 -07:00
common.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
common.h xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
cow_repair.c xfs: remove the expr argument to XFS_TEST_ERROR 2025-09-18 17:32:02 +02:00
dab_bitmap.h xfs: create an xattr iteration function for scrub 2024-04-15 14:58:54 -07:00
dabtree.c xfs: scrub should set preen if attr leaf has holes 2024-04-15 14:58:54 -07:00
dabtree.h xfs: flag empty xattr leaf blocks for optimization 2024-04-15 14:58:54 -07:00
dir.c xfs: scrub metadata directories 2024-11-05 13:38:34 -08:00
dir_repair.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
dirtree.c xfs: scrub metadata directories 2024-11-05 13:38:34 -08:00
dirtree.h xfs: refactor directory tree root predicates 2024-11-05 13:38:33 -08:00
dirtree_repair.c xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
dqiterate.c xfs: improve dquot iteration for scrub 2023-12-15 10:03:45 -08:00
findparent.c xfs: scrub metadata directories 2024-11-05 13:38:34 -08:00
findparent.h xfs: implement live updates for directory repairs 2024-04-23 16:55:13 -07:00
fsb_bitmap.h xfs: reintroduce reaping of file metadata blocks to xrep_reap_extents 2023-12-15 10:03:38 -08:00
fscounters.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
fscounters.h xfs: support RT inodes in xfs_mod_delalloc 2024-04-22 18:00:48 +05:30
fscounters_repair.c xfs: disable sb_frextents for zoned file systems 2025-03-03 08:16:45 -07:00
health.c xfs: scrub the realtime refcount btree 2024-12-23 13:06:14 -08:00
health.h xfs: refactor the btree cursor allocation logic in xchk_ag_btcur_init 2024-02-22 12:39:48 -08:00
ialloc.c xfs: return a 64-bit block count from xfs_btree_count_blocks 2024-12-12 17:45:09 -08:00
ialloc_repair.c xfs: factor out a generic xfs_group structure 2024-11-05 13:38:27 -08:00
ino_bitmap.h xfs: teach online scrub to find directory tree structure problems 2024-04-23 16:55:16 -07:00
inode.c xfs: define the zoned on-disk format 2025-03-03 08:16:45 -07:00
inode_repair.c xfs: kill XBF_UNMAPPED 2025-03-10 14:29:44 +01:00
iscan.c xfs: factor out a generic xfs_group structure 2024-11-05 13:38:27 -08:00
iscan.h xfs: scan the filesystem to repair a directory dotdot entry 2024-04-15 14:58:56 -07:00
listxattr.c xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
listxattr.h xfs: add a per-leaf block callback to xchk_xattr_walk 2024-04-23 16:55:15 -07:00
metapath.c xfs: scrub: use kstrdup_const() for metapath scan setups 2025-09-22 12:57:34 +02:00
newbt.c xfs: remove static reap limits from repair.h 2025-09-05 08:48:23 -07:00
newbt.h xfs: support repairing metadata btrees rooted in metadir inodes 2024-12-23 13:06:08 -08:00
nlinks.c xfs: fix locking in xchk_nlinks_collect_dir 2025-10-22 10:04:39 +02:00
nlinks.h xfs: move files to orphanage instead of letting nlinks drop to zero 2024-04-15 14:58:57 -07:00
nlinks_repair.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
off_bitmap.h xfs: repair problems in CoW forks 2023-12-15 10:03:40 -08:00
orphanage.c Use try_lookup_noperm() instead of d_hash_and_lookup() outside of VFS 2025-04-08 11:24:41 +02:00
orphanage.h xfs: fix corruptions in the directory tree 2024-04-23 16:55:17 -07:00
parent.c xfs: scrub metadata directories 2024-11-05 13:38:34 -08:00
parent_repair.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
quota.c xfs: allow dquot rt block count to exceed rt blocks on reflink fs 2024-12-23 13:06:15 -08:00
quota.h xfs: repair quotas 2023-12-15 10:03:45 -08:00
quota_repair.c xfs: don't flag quota rt block usage on rtreflink filesystems 2024-12-23 13:06:15 -08:00
quotacheck.c xfs: return the allocated transaction from xchk_trans_alloc_empty 2025-07-24 17:30:13 +02:00
quotacheck.h xfs: repair dquots based on live quotacheck results 2024-02-22 12:30:57 -08:00
quotacheck_repair.c xfs: repair dquots based on live quotacheck results 2024-02-22 12:30:57 -08:00
rcbag.c xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
rcbag.h xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
rcbag_btree.c xfs: refactor cmp_key_with_cur routines to take advantage of cmp_int() 2025-07-24 17:30:13 +02:00
rcbag_btree.h xfs: create refcount bag structure for btree repairs 2024-02-22 12:43:41 -08:00
readdir.c xfs: refactor dir format helpers 2024-04-26 11:21:46 +05:30
readdir.h xfs: deferred scrub of dirents 2024-04-23 07:47:02 -07:00
reap.c xfs: use deferred reaping for data device cow extents 2025-09-05 08:48:23 -07:00
reap.h xfs: fix CoW forks for realtime files 2024-12-23 13:06:17 -08:00
refcount.c xfs: namespace the maximum length/refcount symbols 2024-12-23 13:06:10 -08:00
refcount_repair.c xfs: online repair of the realtime refcount btree 2024-12-23 13:06:16 -08:00
repair.c xfs: remove the expr argument to XFS_TEST_ERROR 2025-09-18 17:32:02 +02:00
repair.h xfs: remove static reap limits from repair.h 2025-09-05 08:48:23 -07:00
rgb_bitmap.h xfs: capture realtime CoW staging extents when rebuilding rt rmapbt 2024-12-23 13:06:16 -08:00
rgsuper.c xfs: cross-reference the realtime rmapbt 2024-12-23 13:06:07 -08:00
rmap.c xfs: add a generic group pointer to the btree cursor 2024-11-05 13:38:29 -08:00
rmap_repair.c xfs: remove xrep_trans_{alloc,cancel}_hook_dummy 2025-07-24 17:30:13 +02:00
rtb_bitmap.h xfs: fix CoW forks for realtime files 2024-12-23 13:06:17 -08:00
rtbitmap.c xfs: support xchk_xref_is_used_rt_space on zoned file systems 2025-03-03 08:17:08 -07:00
rtbitmap.h xfs: online repair of realtime bitmaps for a realtime group 2024-12-23 13:06:08 -08:00
rtbitmap_repair.c xfs: check new rtbitmap records against rt refcount btree 2024-12-23 13:06:16 -08:00
rtrefcount.c xfs: online repair of the realtime refcount btree 2024-12-23 13:06:16 -08:00
rtrefcount_repair.c xfs: fixup the metabtree reservation in xrep_reap_metadir_fsblocks 2025-03-03 08:16:43 -07:00
rtrmap.c xfs: allow overlapping rtrmapbt records for shared data extents 2024-12-23 13:06:15 -08:00
rtrmap_repair.c xfs: remove xrep_trans_{alloc,cancel}_hook_dummy 2025-07-24 17:30:13 +02:00
rtsummary.c xfs: allow queued realtime intents to drain before scrubbing 2024-12-23 13:06:06 -08:00
rtsummary.h xfs: replace m_rsumsize with m_rsumblocks 2024-09-01 08:58:19 -07:00
rtsummary_repair.c xfs: online repair of realtime bitmaps for a realtime group 2024-12-23 13:06:08 -08:00
scrub.c xfs: return the allocated transaction from xfs_trans_alloc_empty 2025-07-24 17:30:13 +02:00
scrub.h xfs: constify feature checks 2025-01-13 14:57:08 +01:00
stats.c xfs: scrub the realtime refcount btree 2024-12-23 13:06:14 -08:00
stats.h xfs: track usage statistics of online fsck 2023-08-10 07:48:07 -07:00
symlink.c xfs: online repair of symbolic links 2024-04-15 14:58:58 -07:00
symlink_repair.c xfs: fix out of bounds memory read error in symlink repair 2025-11-20 11:06:24 +01:00
tempexch.h xfs: online repair of realtime bitmaps for a realtime group 2024-12-23 13:06:08 -08:00
tempfile.c xfs: online repair of realtime bitmaps for a realtime group 2024-12-23 13:06:08 -08:00
tempfile.h xfs: move repair temporary files to the metadata directory tree 2024-11-05 13:38:34 -08:00
trace.c xfs: compute per-AG extent reap limits dynamically 2025-09-05 08:48:22 -07:00
trace.h xfs: compute file mapping reap limits dynamically 2025-09-05 08:48:22 -07:00
xfarray.c xfs: drop xfarray sortinfo folio on error 2024-05-27 15:55:52 +05:30
xfarray.h xfs: reduce the rate of cond_resched calls inside scrub 2024-04-23 16:55:17 -07:00
xfblob.c xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
xfblob.h xfs: online repair of directories 2024-04-15 14:58:55 -07:00
xfile.c mm,tmpfs: consider end of file write in shmem_is_huge 2024-09-09 16:39:12 -07:00
xfile.h xfs: repair extended attributes 2024-04-15 14:58:53 -07:00
xfs_scrub.h xfs: introduce vectored scrub mode 2024-04-23 16:55:18 -07:00