linux/fs/xfs
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
..
libxfs xfs: validate btree records on retrieval 2018-06-06 08:12:00 -07:00
scrub xfs: fix xfs_rtalloc_rec units 2018-06-01 09:00:16 -07:00
Kconfig xfs: implement the metadata repair ioctl flag 2018-05-15 18:12:50 -07:00
kmem.c xfs: fall back to vmalloc when allocation log vector buffers 2018-03-11 20:27:55 -07:00
kmem.h xfs: fall back to vmalloc when allocation log vector buffers 2018-03-11 20:27:55 -07:00
Makefile xfs: repair superblocks 2018-05-30 08:03:15 -07:00
mrlock.h
xfs_acl.c xfs: don't change inode mode if ACL update fails 2017-10-11 10:21:06 -07:00
xfs_acl.h xfs: Don't clear SGID when inheriting ACLs 2017-06-27 18:23:21 -07:00
xfs_aops.c xfs: use iomap_bmap 2018-06-01 18:37:33 -07:00
xfs_aops.h xfs, dax: introduce xfs_dax_aops 2018-03-30 11:34:55 -07:00
xfs_attr_inactive.c xfs: fail if xattr inactivation hits a hole 2017-10-26 15:38:22 -07:00
xfs_attr_list.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_attr.h xfs: scrub extended attributes 2017-10-26 15:38:26 -07:00
xfs_bmap_item.c xfs: log item flags are racy 2018-05-10 08:56:41 -07:00
xfs_bmap_item.h xfs: log recovery should replay deferred ops in order 2017-11-27 09:34:08 -08:00
xfs_bmap_util.c xfs: factor out nodiscard helpers 2018-05-15 17:57:05 -07:00
xfs_bmap_util.h xfs: simplify the xfs_getbmap interface 2017-10-26 15:38:20 -07:00
xfs_buf_item.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_buf_item.h Use list_head infra-structure for buffer's log items list 2018-01-29 07:27:22 -08:00
xfs_buf.c xfs: don't retry xfs_buf_find on XBF_TRYLOCK failure 2018-05-09 10:04:00 -07:00
xfs_buf.h xfs: one-shot cached buffers 2018-05-15 18:12:51 -07:00
xfs_dir2_readdir.c xfs: directory scrubber must walk through data block to offset 2018-01-17 21:00:46 -08:00
xfs_discard.c Force log to disk before reading the AGF during a fstrim 2018-04-10 22:39:04 -07:00
xfs_discard.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_dquot_item.c xfs: don't spray logs when dquot flush/purge fail 2018-05-10 08:56:47 -07:00
xfs_dquot_item.h
xfs_dquot.c xfs: refactor dquot iteration 2018-05-15 17:56:59 -07:00
xfs_dquot.h xfs: refactor dquot iteration 2018-05-15 17:56:59 -07:00
xfs_error.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_error.h xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_export.c xfs: push corruption -> ESTALE conversion to xfs_nfs_get_inode() 2018-06-06 08:10:26 -07:00
xfs_export.h
xfs_extent_busy.c xfs: merge _xfs_log_force and xfs_log_force 2018-03-14 11:12:52 -07:00
xfs_extent_busy.h
xfs_extfree_item.c xfs: add bmapi nodiscard flag 2018-05-10 08:56:46 -07:00
xfs_extfree_item.h
xfs_file.c fs: xfs: Change return type to vm_fault_t 2018-05-29 10:46:03 -07:00
xfs_filestream.c xfs: non-scrub - remove unused function parameters 2018-04-09 10:23:42 -07:00
xfs_filestream.h
xfs_fsmap.c xfs: fix xfs_rtalloc_rec units 2018-06-01 09:00:16 -07:00
xfs_fsmap.h xfs: implement the GETFSMAP ioctl 2017-04-03 15:18:17 -07:00
xfs_fsops.c xfs: factor the ag length extension code into libxfs 2018-05-15 18:12:51 -07:00
xfs_fsops.h xfs: hoist xfs_fs_geometry to libxfs 2018-01-08 10:54:48 -08:00
xfs_globals.c xfs: add mount delay debug option 2018-05-15 17:57:05 -07:00
xfs_icache.c xfs: halt auto-reclamation activities while rebuilding rmap 2018-05-15 17:57:05 -07:00
xfs_icache.h xfs: halt auto-reclamation activities while rebuilding rmap 2018-05-15 17:57:05 -07:00
xfs_icreate_item.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_icreate_item.h
xfs_inode_item.c xfs: log item flags are racy 2018-05-10 08:56:41 -07:00
xfs_inode_item.h xfs: remove inode log format typedef 2017-11-01 15:03:16 -07:00
xfs_inode.c xfs: don't assert on corrupted unlinked inode list 2018-06-04 18:25:05 -07:00
xfs_inode.h xfs: factor out nodiscard helpers 2018-05-15 17:57:05 -07:00
xfs_ioctl32.c xfs: refactor the geometry structure filling function 2018-01-08 10:54:48 -08:00
xfs_ioctl32.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_ioctl.c xfs: don't forbid setting dax flag on directories if device doesn't dax 2018-06-04 14:45:29 -07:00
xfs_ioctl.h xfs: remove u_int* type usage 2017-11-09 15:50:29 -08:00
xfs_iomap.c xfs: split out dqget for inodes from regular dqget 2018-05-10 08:56:48 -07:00
xfs_iomap.h xfs: update i_size after unwritten conversion in dio completion 2017-09-26 10:55:19 -07:00
xfs_iops.c fs: allow per-device dax status checking for filesystems 2018-05-31 08:58:33 -07:00
xfs_iops.h
xfs_itable.c xfs: remove if_rdev 2017-10-26 15:38:27 -07:00
xfs_itable.h xfs: create inode pointer verifiers 2017-10-26 15:38:23 -07:00
xfs_linux.h xfs: use %px for data pointers when debugging 2018-01-12 14:09:08 -08:00
xfs_log_cil.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_log_priv.h locking/atomics: COCCINELLE/treewide: Convert trivial ACCESS_ONCE() patterns to READ_ONCE()/WRITE_ONCE() 2017-10-25 11:01:08 +02:00
xfs_log_recover.c xfs: explicitly pass buffer size to xfs_corruption_error 2018-06-04 18:25:05 -07:00
xfs_log.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_log.h xfs: non-scrub - remove unused function parameters 2018-04-09 10:23:42 -07:00
xfs_message.c xfs: define bug_on_assert debug mode sysfs tunable 2017-06-19 08:59:10 -07:00
xfs_message.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_mount.c xfs: verify root inode more thoroughly 2018-06-06 08:10:26 -07:00
xfs_mount.h xfs: detect agfl count corruption and reset agfl 2018-03-23 18:05:06 -07:00
xfs_mru_cache.c xfs: remove filestream item xfs_inode reference 2018-04-09 10:23:39 -07:00
xfs_mru_cache.h xfs: remove filestream item xfs_inode reference 2018-04-09 10:23:39 -07:00
xfs_ondisk.h xfs: Don't log uninitialised fields in inode structures 2017-10-11 10:21:06 -07:00
xfs_pnfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_pnfs.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_qm_bhv.c xfs: replace XFS_QMOPT_DQALLOC with a simple boolean 2018-05-10 08:56:48 -07:00
xfs_qm_syscalls.c xfs: replace XFS_QMOPT_DQALLOC with a simple boolean 2018-05-10 08:56:48 -07:00
xfs_qm.c xfs: refactor quota limits initialization 2018-05-15 17:57:05 -07:00
xfs_qm.h xfs: refactor XFS_QMOPT_DQNEXT out of existence 2018-05-10 08:56:47 -07:00
xfs_quota.h xfs: add helpers to attach quotas to inodes 2018-05-30 08:03:15 -07:00
xfs_quotaops.c xfs: refactor XFS_QMOPT_DQNEXT out of existence 2018-05-10 08:56:47 -07:00
xfs_refcount_item.c xfs: log item flags are racy 2018-05-10 08:56:41 -07:00
xfs_refcount_item.h xfs: log recovery should replay deferred ops in order 2017-11-27 09:34:08 -08:00
xfs_reflink.c xfs: split out dqget for inodes from regular dqget 2018-05-10 08:56:48 -07:00
xfs_reflink.h xfs: separate function to check if inode shares extents 2017-06-19 14:11:35 -07:00
xfs_rmap_item.c xfs: log item flags are racy 2018-05-10 08:56:41 -07:00
xfs_rmap_item.h
xfs_rtalloc.c xfs: remove the ip argument to xfs_defer_finish 2017-09-01 10:55:30 -07:00
xfs_rtalloc.h xfs: fix xfs_rtalloc_rec units 2018-06-01 09:00:16 -07:00
xfs_stats.c xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_stats.h xfs: remove double-underscore integer types 2017-06-19 14:11:33 -07:00
xfs_super.c dax: change bdev_dax_supported() to support boolean returns 2018-05-31 08:58:34 -07:00
xfs_super.h xfs: add scrub to XFS_BUILD_OPTIONS 2018-02-01 21:06:15 -08:00
xfs_symlink.c xfs: fix double ijoin in xfs_inactive_symlink_rmt() 2018-05-10 08:56:46 -07:00
xfs_symlink.h xfs: allow reading of already-locked remote symbolic link 2017-06-20 10:45:22 -07:00
xfs_sysctl.c
xfs_sysctl.h xfs: add mount delay debug option 2018-05-15 17:57:05 -07:00
xfs_sysfs.c xfs: add mount delay debug option 2018-05-15 17:57:05 -07:00
xfs_sysfs.h
xfs_trace.c fs: xfs: remove duplicate includes 2017-12-08 17:51:05 -08:00
xfs_trace.h xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_ail.c xfs: don't assert fail with AIL lock held 2018-05-10 08:56:46 -07:00
xfs_trans_bmap.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_buf.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_dquot.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_extfree.c xfs: factor out nodiscard helpers 2018-05-15 17:57:05 -07:00
xfs_trans_inode.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_priv.h xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_refcount.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans_rmap.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans.c xfs: get rid of the log item descriptor 2018-05-10 08:56:46 -07:00
xfs_trans.h xfs: add bmapi nodiscard flag 2018-05-10 08:56:46 -07:00
xfs_xattr.c
xfs.h xfs: always define STATIC to static noinline 2017-11-06 11:53:58 -08:00