linux/fs/xfs/libxfs
Dave Chinner 9e6c08d4a8 xfs: validate btree records on retrieval
So we don't check the validity of records as we walk the btree. When
there are corrupt records in the free space btree (e.g. zero
startblock/length or beyond EOAG) we just blindly use it and things
go bad from there. That leads to assert failures on debug kernels
like this:

XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_alloc.c, line: 450
....
Call Trace:
 xfs_alloc_fixup_trees+0x368/0x5c0
 xfs_alloc_ag_vextent_near+0x79a/0xe20
 xfs_alloc_ag_vextent+0x1d3/0x330
 xfs_alloc_vextent+0x5e9/0x870

Or crashes like this:

XFS (loop0): xfs_buf_find: daddr 0x7fb28 out of range, EOFS 0x8000
.....
BUG: unable to handle kernel NULL pointer dereference at 00000000000000c8
....
Call Trace:
 xfs_bmap_add_extent_hole_real+0x67d/0x930
 xfs_bmapi_write+0x934/0xc90
 xfs_da_grow_inode_int+0x27e/0x2f0
 xfs_dir2_grow_inode+0x55/0x130
 xfs_dir2_sf_to_block+0x94/0x5d0
 xfs_dir2_sf_addname+0xd0/0x590
 xfs_dir_createname+0x168/0x1a0
 xfs_rename+0x658/0x9b0

By checking that free space records pulled from the trees are
within the valid range, we catch many of these corruptions before
they can do damage.

This is a generic btree record checking deficiency. We need to
validate the records we fetch from all the different btrees before
we use them to catch corruptions like this.

This patch results in a corrupt record emitting an error message and
returning -EFSCORRUPTED, and the higher layers catch that and abort:

 XFS (loop0): Size Freespace BTree record corruption in AG 0 detected!
 XFS (loop0): start block 0x0 block count 0x0
 XFS (loop0): Internal error xfs_trans_cancel at line 1012 of file fs/xfs/xfs_trans.c.  Caller xfs_create+0x42a/0x670
 .....
 Call Trace:
  dump_stack+0x85/0xcb
  xfs_trans_cancel+0x19f/0x1c0
  xfs_create+0x42a/0x670
  xfs_generic_create+0x1f6/0x2c0
  vfs_create+0xf9/0x180
  do_mknodat+0x1f9/0x210
  do_syscall_64+0x5a/0x180
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
.....
 XFS (loop0): xfs_do_force_shutdown(0x8) called from line 1013 of file fs/xfs/xfs_trans.c.  Return address = ffffffff81500868
 XFS (loop0): Corruption of in-memory data detected.  Shutting down filesystem

Signed-off-by: Dave Chinner <dchinner@redhat.com>

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
2018-06-06 08:12:00 -07:00
..
xfs_ag_resv.c xfs: account only rmapbt-used blocks against rmapbt perag res 2018-03-11 20:27:57 -07:00
xfs_ag_resv.h xfs: account only rmapbt-used blocks against rmapbt perag res 2018-03-11 20:27:57 -07:00
xfs_ag.c xfs: factor the ag length extension code into libxfs 2018-05-15 18:12:51 -07:00
xfs_ag.h xfs: factor the ag length extension code into libxfs 2018-05-15 18:12:51 -07:00
xfs_alloc_btree.c xfs: don't ASSERT on short form btree root pointer of zero 2018-06-04 14:45:30 -07:00
xfs_alloc_btree.h xfs: add helpers to calculate btree size 2018-05-15 17:57:05 -07:00
xfs_alloc.c xfs: validate btree records on retrieval 2018-06-06 08:12:00 -07:00
xfs_alloc.h xfs: hoist xfs_scrub_agfl_walk to libxfs as xfs_agfl_walk 2018-05-15 18:12:50 -07:00
xfs_attr_leaf.c Split buffer's b_fspriv field 2018-01-29 07:27:22 -08:00
xfs_attr_leaf.h xfs: create structure verifier function for shortform xattrs 2018-01-08 10:54:46 -08:00
xfs_attr_remote.c xfs: make xfs_buf_incore out of line 2018-05-09 10:04:00 -07:00
xfs_attr_remote.h
xfs_attr_sf.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_attr.c xfs: remove unnecessary xfs_qm_dqattach parameter 2018-05-10 08:56:47 -07:00
xfs_bit.c libxfs: Optimize the loop for xfs_bitmap_empty 2016-01-04 16:10:19 +11:00
xfs_bit.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_bmap_btree.c xfs: add helpers to calculate btree size 2018-05-15 17:57:05 -07:00
xfs_bmap_btree.h xfs: add helpers to calculate btree size 2018-05-15 17:57:05 -07:00
xfs_bmap.c xfs: don't assert when reporting on-disk corruption while loading btree 2018-06-04 14:45:29 -07:00
xfs_bmap.h xfs: make xfs_bmapi_remapi work with attribute forks 2018-05-15 18:12:50 -07:00
xfs_btree.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_btree.h xfs: add repair helpers for the reference count btree 2018-05-15 17:57:05 -07:00
xfs_cksum.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_da_btree.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_da_btree.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_da_format.c xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_da_format.h xfs: refactor the geometry structure filling function 2018-01-08 10:54:48 -08:00
xfs_defer.c xfs: adder caller IP to xfs_defer* tracepoints 2018-05-10 08:56:46 -07:00
xfs_defer.h xfs: defer agfl block frees when dfops is available 2018-05-09 10:04:02 -07:00
xfs_dir2_block.c xfs: sanity-check the unused space before trying to use it 2018-03-23 18:05:07 -07:00
xfs_dir2_data.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_dir2_leaf.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_dir2_node.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_dir2_priv.h xfs: refactor short form directory structure verifier function 2018-01-08 10:54:46 -08:00
xfs_dir2_sf.c xfs: directory scrubber must walk through data block to offset 2018-01-17 21:00:46 -08:00
xfs_dir2.c xfs: refactor the geometry structure filling function 2018-01-08 10:54:48 -08:00
xfs_dir2.h xfs: sanity-check the unused space before trying to use it 2018-03-23 18:05:07 -07:00
xfs_dquot_buf.c xfs: print specific dqblk that failed verifiers 2018-05-09 10:04:01 -07:00
xfs_errortag.h xfs: implement the metadata repair ioctl flag 2018-05-15 18:12:50 -07:00
xfs_format.h xfs: implement online get/set fs label 2018-05-16 08:50:16 -07:00
xfs_fs.h xfs: implement the metadata repair ioctl flag 2018-05-15 18:12:50 -07:00
xfs_ialloc_btree.c xfs: fix inobt magic number check 2018-05-29 10:46:03 -07:00
xfs_ialloc_btree.h xfs: add helpers to calculate btree size 2018-05-15 17:57:05 -07:00
xfs_ialloc.c xfs: validate btree records on retrieval 2018-06-06 08:12:00 -07:00
xfs_ialloc.h xfs: expose various functions to repair code 2018-05-15 17:57:05 -07:00
xfs_iext_tree.c xfs: move xfs_iext_insert tracepoint to report useful information 2017-12-14 09:20:11 -08:00
xfs_inode_buf.c xfs: push corruption -> ESTALE conversion to xfs_nfs_get_inode() 2018-06-06 08:10:26 -07:00
xfs_inode_buf.h xfs: move inode extent size hint validation to libxfs 2018-03-23 18:05:08 -07:00
xfs_inode_fork.c xfs: refactor inode verifier error logging 2018-03-23 18:05:07 -07:00
xfs_inode_fork.h xfs: provide a centralized method for verifying inline fork data 2018-01-08 10:54:47 -08:00
xfs_log_format.h xfs: fix type usage 2017-11-16 12:06:45 -08:00
xfs_log_recover.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_log_rlimit.c xfs: trace log reservations at mount time 2018-01-08 10:54:47 -08:00
xfs_quota_defs.h xfs: replace XFS_QMOPT_DQALLOC with a simple boolean 2018-05-10 08:56:48 -07:00
xfs_refcount_btree.c xfs: don't ASSERT on short form btree root pointer of zero 2018-06-04 14:45:30 -07:00
xfs_refcount_btree.h xfs: non-scrub - remove unused function parameters 2018-04-09 10:23:42 -07:00
xfs_refcount.c xfs: validate btree records on retrieval 2018-06-06 08:12:00 -07:00
xfs_refcount.h xfs: add repair helpers for the reference count btree 2018-05-15 17:57:05 -07:00
xfs_rmap_btree.c xfs: don't ASSERT on short form btree root pointer of zero 2018-06-04 14:45:30 -07:00
xfs_rmap_btree.h xfs: non-scrub - remove unused function parameters 2018-04-09 10:23:42 -07:00
xfs_rmap.c xfs: validate btree records on retrieval 2018-06-06 08:12:00 -07:00
xfs_rmap.h xfs: add repair helpers for the reverse mapping btree 2018-05-15 17:57:05 -07:00
xfs_rtbitmap.c xfs: fix xfs_rtalloc_rec units 2018-06-01 09:00:16 -07:00
xfs_sb.c xfs: catch bad stripe alignment configurations 2018-06-06 08:10:26 -07:00
xfs_sb.h xfs: repair superblocks 2018-05-30 08:03:15 -07:00
xfs_shared.h xfs: superblock scrub should use short-lived buffers 2018-05-15 17:57:05 -07:00
xfs_symlink_remote.c Split buffer's b_fspriv field 2018-01-29 07:27:22 -08:00
xfs_trans_resv.c xfs: non-scrub - remove unused function parameters 2018-04-09 10:23:42 -07:00
xfs_trans_resv.h xfs: increase log reservations for reflink 2016-10-05 16:26:29 -07:00
xfs_trans_space.h xfs: reserve enough blocks to handle btree splits when remapping 2017-05-03 13:21:40 -07:00
xfs_types.h xfs: xfs_rtword_t should be unsigned, not signed 2018-06-01 09:00:16 -07:00