mirror_ubuntu-kernels/fs/xfs/libxfs
Long Li c3b880acad xfs: fix ag count overflow during growfs
I found a corruption during growfs:

 XFS (loop0): Internal error agbno >= mp->m_sb.sb_agblocks at line 3661 of
   file fs/xfs/libxfs/xfs_alloc.c.  Caller __xfs_free_extent+0x28e/0x3c0
 CPU: 0 PID: 573 Comm: xfs_growfs Not tainted 6.3.0-rc7-next-20230420-00001-gda8c95746257
 Call Trace:
  <TASK>
  dump_stack_lvl+0x50/0x70
  xfs_corruption_error+0x134/0x150
  __xfs_free_extent+0x2c1/0x3c0
  xfs_ag_extend_space+0x291/0x3e0
  xfs_growfs_data+0xd72/0xe90
  xfs_file_ioctl+0x5f9/0x14a0
  __x64_sys_ioctl+0x13e/0x1c0
  do_syscall_64+0x39/0x80
  entry_SYSCALL_64_after_hwframe+0x63/0xcd
 XFS (loop0): Corruption detected. Unmount and run xfs_repair
 XFS (loop0): Internal error xfs_trans_cancel at line 1097 of file
   fs/xfs/xfs_trans.c.  Caller xfs_growfs_data+0x691/0xe90
 CPU: 0 PID: 573 Comm: xfs_growfs Not tainted 6.3.0-rc7-next-20230420-00001-gda8c95746257
 Call Trace:
  <TASK>
  dump_stack_lvl+0x50/0x70
  xfs_error_report+0x93/0xc0
  xfs_trans_cancel+0x2c0/0x350
  xfs_growfs_data+0x691/0xe90
  xfs_file_ioctl+0x5f9/0x14a0
  __x64_sys_ioctl+0x13e/0x1c0
  do_syscall_64+0x39/0x80
  entry_SYSCALL_64_after_hwframe+0x63/0xcd
 RIP: 0033:0x7f2d86706577

The bug can be reproduced with the following sequence:

 # truncate -s  1073741824 xfs_test.img
 # mkfs.xfs -f -b size=1024 -d agcount=4 xfs_test.img
 # truncate -s 2305843009213693952  xfs_test.img
 # mount -o loop xfs_test.img /mnt/test
 # xfs_growfs -D  1125899907891200  /mnt/test

The root cause is that during growfs, user space passed in a large value
of newblcoks to xfs_growfs_data_private(), due to current sb_agblocks is
too small, new AG count will exceed UINT_MAX. Because of AG number type
is unsigned int and it would overflow, that caused nagcount much smaller
than the actual value. During AG extent space, delta blocks in
xfs_resizefs_init_new_ags() will much larger than the actual value due to
incorrect nagcount, even exceed UINT_MAX. This will cause corruption and
be detected in __xfs_free_extent. Fix it by growing the filesystem to up
to the maximally allowed AGs and not return EINVAL when new AG count
overflow.

Signed-off-by: Long Li <leo.lilong@huawei.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
2023-06-13 08:49:20 -07:00
..
xfs_ag_resv.c xfs: inobt can use perags in many more places than it does 2023-02-13 09:14:52 +11:00
xfs_ag_resv.h xfs: move perag structure and setup to libxfs/xfs_ag.[ch] 2021-06-02 10:48:24 +10:00
xfs_ag.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_ag.h xfs: allow queued AG intents to drain before scrubbing 2023-04-11 18:59:58 -07:00
xfs_alloc_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_alloc_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_alloc.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_alloc.h xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_attr_leaf.c xfs: don't leak memory when attr fork loading fails 2022-07-20 16:40:39 -07:00
xfs_attr_leaf.h xfs: don't hold xattr leaf buffers across transaction rolls 2022-06-29 08:47:56 -07:00
xfs_attr_remote.c xfs: rework xfs_buf_incore() API 2022-07-07 22:05:18 +10:00
xfs_attr_remote.h xfs: rename struct xfs_attr_item to xfs_attr_intent 2022-05-22 16:00:26 +10:00
xfs_attr_sf.h xfs: Convert xfs_attr_sf macros to inline functions 2020-09-15 20:52:42 -07:00
xfs_attr.c xfs: replace XFS_IFORK_Q with a proper predicate function 2022-07-12 11:17:27 -07:00
xfs_attr.h xfs: replace XFS_IFORK_Q with a proper predicate function 2022-07-12 11:17:27 -07:00
xfs_bit.c xfs: fix missing header includes 2019-11-07 13:00:53 -08:00
xfs_bit.h xfs: Use the correct style for SPDX License Identifier 2020-05-13 15:32:45 -07:00
xfs_bmap_btree.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_bmap_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_bmap.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_bmap.h xfs: accumulate iextent records when checking bmap 2023-04-11 19:00:24 -07:00
xfs_btree_staging.c xfs: encode the max btree height in the cursor 2021-10-19 11:45:15 -07:00
xfs_btree_staging.h xfs: xfs_btree_staging.h: delete duplicated words 2020-07-28 20:24:14 -07:00
xfs_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_btree.h xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_cksum.h
xfs_da_btree.c xfs: trim the mapp array accordingly in xfs_da_grow_inode_int 2022-10-04 16:39:42 +11:00
xfs_da_btree.h xfs: fix TOCTOU race involving the new logged xattrs control knob 2022-06-15 23:13:32 -07:00
xfs_da_format.h Merge tag 'large-extent-counters-v9' of https://github.com/chandanr/linux into xfs-5.19-for-next 2022-04-21 16:46:17 +10:00
xfs_defer.c xfs: allow queued AG intents to drain before scrubbing 2023-04-11 18:59:58 -07:00
xfs_defer.h xfs: Implement attr logging and replay 2022-05-09 19:09:07 +10:00
xfs_dir2_block.c xfs: replace inode fork size macros with functions 2022-07-12 11:17:27 -07:00
xfs_dir2_data.c xfs: convert bp->b_bn references to xfs_buf_daddr() 2021-08-19 10:07:15 -07:00
xfs_dir2_leaf.c xfs: fix exception caused by unexpected illegal bestcount in leaf dir 2022-10-20 09:42:56 -07:00
xfs_dir2_node.c xfs: convert bp->b_bn references to xfs_buf_daddr() 2021-08-19 10:07:15 -07:00
xfs_dir2_priv.h xfs: constify the name argument to various directory functions 2022-03-14 10:23:17 -07:00
xfs_dir2_sf.c xfs: Remove the unneeded result variable 2022-09-19 06:52:14 +10:00
xfs_dir2.c xfs: stabilize the dirent name transformation function used for ascii-ci dir hash computation 2023-04-11 19:05:04 -07:00
xfs_dir2.h xfs: stabilize the dirent name transformation function used for ascii-ci dir hash computation 2023-04-11 19:05:04 -07:00
xfs_dquot_buf.c xfs: remove the xfs_dqblk_t typedef 2021-10-14 09:19:33 -07:00
xfs_errortag.h xfs: add debug knob to slow down write for fun 2022-11-28 17:54:49 -08:00
xfs_format.h xfs: rename XFS_REFC_COW_START to _COWFLAG 2022-10-31 08:58:22 -07:00
xfs_fs.h xfs: fix ag count overflow during growfs 2023-06-13 08:49:20 -07:00
xfs_health.h xfs: Use the correct style for SPDX License Identifier 2020-05-13 15:32:45 -07:00
xfs_ialloc_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_ialloc_btree.h xfs: standardize ondisk to incore conversion for inode btrees 2023-04-11 19:00:01 -07:00
xfs_ialloc.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_ialloc.h xfs: convert xfs_ialloc_has_inodes_at_extent to return keyfill scan results 2023-04-11 19:00:15 -07:00
xfs_iext_tree.c xfs: prevent metadata files from being inactivated 2021-03-25 16:47:50 -07:00
xfs_inode_buf.c xfs: make attr forks permanent 2022-07-14 09:46:37 -07:00
xfs_inode_buf.h xfs: kill xfs_sb_version_has_v3inode() 2021-08-19 10:07:14 -07:00
xfs_inode_fork.c xfs: standardize btree record checking code [v24.5] 2023-04-14 07:09:18 +10:00
xfs_inode_fork.h xfs: _{attr,data}_map_shared should take ILOCK_EXCL until iread_extents is completely done 2023-04-12 15:49:10 +10:00
xfs_log_format.h xfs: fix AGF vs inode cluster buffer deadlock 2023-06-05 04:08:27 +10:00
xfs_log_recover.h xfs: convert buf_cancel_table allocation to kmalloc_array 2022-05-27 10:27:19 +10:00
xfs_log_rlimit.c xfs: reduce transaction reservations with reflink 2022-04-28 10:25:42 -07:00
xfs_quota_defs.h xfs: remove warning counters from struct xfs_dquot_res 2022-05-11 17:12:09 +10:00
xfs_refcount_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_refcount_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_refcount.c xfs: validate block number being freed before adding to xefi 2023-06-05 14:48:15 +10:00
xfs_refcount.h xfs: replace xfs_btree_has_record with a general keyspace scanner 2023-04-11 19:00:10 -07:00
xfs_rmap_btree.c xfs: implement masked btree key comparisons for _has_records scans 2023-04-11 19:00:11 -07:00
xfs_rmap_btree.h xfs: use separate btree cursor cache for each btree type 2021-10-19 11:45:16 -07:00
xfs_rmap.c xfs: teach scrub to check for sole ownership of metadata objects 2023-04-11 19:00:15 -07:00
xfs_rmap.h xfs: teach scrub to check for sole ownership of metadata objects 2023-04-11 19:00:15 -07:00
xfs_rtbitmap.c xfs: pass explicit mount pointer to rtalloc query functions 2022-04-12 06:49:41 +10:00
xfs_sb.c xfs: don't consider future format versions valid 2023-04-12 15:48:50 +10:00
xfs_sb.h xfs: open code sb verifier feature checks 2021-08-19 10:07:13 -07:00
xfs_shared.h xfs: tag transactions that contain intent done items 2022-05-04 11:46:21 +10:00
xfs_symlink_remote.c xfs: convert XFS_IFORK_PTR to a static inline helper 2022-07-09 15:17:21 -07:00
xfs_trans_inode.c xfs: fix AGF vs inode cluster buffer deadlock 2023-06-05 04:08:27 +10:00
xfs_trans_resv.c xfs: increase rename inode reservation 2022-10-26 13:02:24 -07:00
xfs_trans_resv.h xfs: rename xfs_*alloc*_log_count to _block_count 2022-04-28 10:25:59 -07:00
xfs_trans_space.h xfs: compute the maximum height of the rmap btree when reflink enabled 2021-10-19 11:45:16 -07:00
xfs_types.c xfs: Pre-calculate per-AG agino geometry 2022-07-07 19:13:10 +10:00
xfs_types.h xfs: replace xfs_btree_has_record with a general keyspace scanner 2023-04-11 19:00:10 -07:00