Skip to content

Commit

Permalink
xfs: clear sb->s_fs_info on mount failure
Browse files Browse the repository at this point in the history
commit c9fbd7b upstream.

We recently had an oops reported on a 4.14 kernel in
xfs_reclaim_inodes_count() where sb->s_fs_info pointed to garbage
and so the m_perag_tree lookup walked into lala land.

Essentially, the machine was under memory pressure when the mount
was being run, xfs_fs_fill_super() failed after allocating the
xfs_mount and attaching it to sb->s_fs_info. It then cleaned up and
freed the xfs_mount, but the sb->s_fs_info field still pointed to
the freed memory. Hence when the superblock shrinker then ran
it fell off the bad pointer.

With the superblock shrinker problem fixed at teh VFS level, this
stale s_fs_info pointer is still a problem - we use it
unconditionally in ->put_super when the superblock is being torn
down, and hence we can still trip over it after a ->fill_super
call failure. Hence we need to clear s_fs_info if
xfs-fs_fill_super() fails, and we need to check if it's valid in
the places it can potentially be dereferenced after a ->fill_super
failure.

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>
Signed-off-by: Ajay Kaher <akaher@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dave Chinner authored and Greg Kroah-Hartman committed Oct 17, 2019
1 parent 1cf0865 commit e6e3f36
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions fs/xfs/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1674,6 +1674,7 @@ xfs_fs_fill_super(
out_close_devices:
xfs_close_devices(mp);
out_free_fsname:
sb->s_fs_info = NULL;
xfs_free_fsname(mp);
kfree(mp);
out:
Expand All @@ -1691,6 +1692,10 @@ xfs_fs_put_super(
{
struct xfs_mount *mp = XFS_M(sb);

/* if ->fill_super failed, we have no mount to tear down */
if (!sb->s_fs_info)
return;

xfs_notice(mp, "Unmounting Filesystem");
xfs_filestream_unmount(mp);
xfs_unmountfs(mp);
Expand All @@ -1700,6 +1705,8 @@ xfs_fs_put_super(
xfs_destroy_percpu_counters(mp);
xfs_destroy_mount_workqueues(mp);
xfs_close_devices(mp);

sb->s_fs_info = NULL;
xfs_free_fsname(mp);
kfree(mp);
}
Expand All @@ -1719,6 +1726,9 @@ xfs_fs_nr_cached_objects(
struct super_block *sb,
struct shrink_control *sc)
{
/* Paranoia: catch incorrect calls during mount setup or teardown */
if (WARN_ON_ONCE(!sb->s_fs_info))
return 0;
return xfs_reclaim_inodes_count(XFS_M(sb));
}

Expand Down

0 comments on commit e6e3f36

Please sign in to comment.