mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-11-07 23:04:53 +03:00
Fix get_zfs_sb race with concurrent umount
Certain ioctl operations will call get_zfs_sb, which will holds an active
count on sb without checking whether it's active or not. This will result
in use-after-free. We fix this by using atomic_inc_not_zero to make sure
we got an active sb.
P1 P2
--- ---
deactivate_locked_super(): s_active = 0
zfs_sb_hold()
->get_zfs_sb(): s_active = 1
->zpl_kill_sb()
-->zpl_put_super()
--->zfs_umount()
---->zfs_sb_free(zsb)
zfs_sb_rele(zsb)
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
590c9a0994
commit
061460dfe2
@ -1393,9 +1393,9 @@ get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
|
||||
|
||||
mutex_enter(&os->os_user_ptr_lock);
|
||||
*zsbp = dmu_objset_get_user(os);
|
||||
if (*zsbp && (*zsbp)->z_sb) {
|
||||
atomic_inc(&((*zsbp)->z_sb->s_active));
|
||||
} else {
|
||||
/* bump s_active only when non-zero to prevent umount race */
|
||||
if (*zsbp == NULL || (*zsbp)->z_sb == NULL ||
|
||||
!atomic_inc_not_zero(&((*zsbp)->z_sb->s_active))) {
|
||||
error = SET_ERROR(ESRCH);
|
||||
}
|
||||
mutex_exit(&os->os_user_ptr_lock);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user