mirror_zfs/module/os/linux/zfs
Christian Schwarz 4d5aef3ba9
zfs_domount: fix double-disown of dataset / double-free of zfsvfs_t
Before this patch, in zfs_domount, if zfs_root or d_make_root fails, we
leave zfsvfs != NULL. This will lead to execution of the error handling
`if` statement at the `out` label, and hence to a call to
dmu_objset_disown and zfsvfs_free.

However, zfs_umount, which we call upon failure of zfs_root and
d_make_root already does dmu_objset_disown and zfsvfs_free.

I suppose this patch rather adds to the brittleness of this part of the
code base, but I don't want to invest more time in this right now.
To add a regression test, we'd need some kind of fault injection
facility for zfs_root or d_make_root, which doesn't exist right now.
And even then, I think that regression test would be too closely tied
to the implementation.

To repro the double-disown / double-free, do the following:
1. patch zfs_root to always return an error
2. mount a ZFS filesystem

Here's the stack trace you would see then:

  VERIFY3(ds->ds_owner == tag) failed (0000000000000000 == ffff9142361e8000)
  PANIC at dsl_dataset.c:1003:dsl_dataset_disown()
  Showing stack for process 28332
  CPU: 2 PID: 28332 Comm: zpool Tainted: G           O      5.10.103-1.nutanix.el7.x86_64 #1
  Call Trace:
   dump_stack+0x74/0x92
   spl_dumpstack+0x29/0x2b [spl]
   spl_panic+0xd4/0xfc [spl]
   dsl_dataset_disown+0xe9/0x150 [zfs]
   dmu_objset_disown+0xd6/0x150 [zfs]
   zfs_domount+0x17b/0x4b0 [zfs]
   zpl_mount+0x174/0x220 [zfs]
   legacy_get_tree+0x2b/0x50
   vfs_get_tree+0x2a/0xc0
   path_mount+0x2fa/0xa70
   do_mount+0x7c/0xa0
   __x64_sys_mount+0x8b/0xe0
   do_syscall_64+0x38/0x50
   entry_SYSCALL_64_after_hwframe+0x44/0xa9

Reviewed-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Co-authored-by: Christian Schwarz <christian.schwarz@nutanix.com>
Signed-off-by: Christian Schwarz <christian.schwarz@nutanix.com>
Closes #14025
2022-10-14 11:46:47 -07:00
..
abd_os.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
arc_os.c Cleanup: 64-bit kernel module parameters should use fixed width types 2022-10-13 10:03:29 -07:00
mmp_os.c Cleanup: 64-bit kernel module parameters should use fixed width types 2022-10-13 10:03:29 -07:00
policy.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
qat_compress.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
qat_crypt.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
qat.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
spa_misc_os.c Cleanup: 64-bit kernel module parameters should use fixed width types 2022-10-13 10:03:29 -07:00
trace.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
vdev_disk.c Cleanup: 64-bit kernel module parameters should use fixed width types 2022-10-13 10:03:29 -07:00
vdev_file.c Cleanup: 64-bit kernel module parameters should use fixed width types 2022-10-13 10:03:29 -07:00
zfs_acl.c Add defensive assertions 2022-10-12 11:25:18 -07:00
zfs_ctldir.c zfs_enter rework 2022-09-16 13:36:47 -07:00
zfs_debug.c Cleanup: Specify unsignedness on things that should not be signed 2022-09-27 16:42:41 -07:00
zfs_dir.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zfs_file_os.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zfs_ioctl_os.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zfs_racct.c module: zfs: fix unused, remove argsused 2021-12-23 09:42:47 -08:00
zfs_sysfs.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zfs_uio.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zfs_vfsops.c zfs_domount: fix double-disown of dataset / double-free of zfsvfs_t 2022-10-14 11:46:47 -07:00
zfs_vnops_os.c zfs_enter rework 2022-09-16 13:36:47 -07:00
zfs_znode.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zio_crypt.c Avoid calling rw_destroy() on uninitialized rwlock 2022-10-05 17:07:50 -07:00
zpl_ctldir.c Fix double const qualifier declarations 2022-09-30 15:34:39 -07:00
zpl_export.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zpl_file.c zfs_enter rework followup 2022-09-16 14:25:53 -07:00
zpl_inode.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
zpl_super.c zfs_enter rework 2022-09-16 13:36:47 -07:00
zpl_xattr.c zfs_enter rework 2022-09-16 13:36:47 -07:00
zvol_os.c Cleanup: Remove ineffective unsigned comparisons against 0 2022-09-26 17:02:38 -07:00