• D
    xfs: validate btree records on retrieval · 9e6c08d4
    Dave Chinner 提交于
    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: NDave Chinner <dchinner@redhat.com>
    Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
    9e6c08d4
xfs_refcount.c 47.9 KB