Skip to content

Commit

Permalink
Fix use-after-free after unmount
Browse files Browse the repository at this point in the history
During unmount `zfsvfs` is destroyed and the pointer is zeroed in
the VCB. There is however still a copy of the pointer in the DCB.

Windows can still call into `zfs_AcquireForLazyWrite` through `CcMgr`
after unmount and this would use the already freed `zfsvfs` pointer.

To fix this we set the pointer to zero in the DCB and add a zero check
in `zfs_AcquireForLazyWrite`.

Signed-off-by: Axel Gembe <[email protected]>
  • Loading branch information
EchterAgo committed Oct 13, 2023
1 parent fee66c7 commit 73b95fb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
10 changes: 10 additions & 0 deletions module/os/windows/zfs/zfs_vnops_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ zfs_AcquireForLazyWrite(void *Context, BOOLEAN Wait)
struct vnode *vp = fo->FsContext;
dprintf("%s:fo %p\n", __func__, fo);

if (unlikely((zmo->vpb->Flags & VPB_MOUNTED) == 0)) {
dprintf("%s: fo %p not mounted\n", __func__, fo);
return (FALSE);
}

if (unlikely(zfsvfs == NULL)) {
dprintf("%s: fo %p already freed zfsvfs\n", __func__, fo);
return (FALSE);
}

/* Confirm we are mounted, and stop unmounting */
if (vfs_busy(zfsvfs->z_vfs, 0) != 0)
return (FALSE);
Expand Down
6 changes: 6 additions & 0 deletions module/os/windows/zfs/zfs_vnops_windows_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,12 @@ zfs_windows_unmount(zfs_cmd_t *zc)
if (error)
goto out_unlock;

if (likely(zmo_dcb != NULL)) {
// zfs_vfs_unmount already freed the zfsvfs, but
// a reference still exists in the DCB.
vfs_setfsprivate(zmo_dcb, NULL);
}

// Release devices
IoDeleteSymbolicLink(&zmo->symlink_name);

Expand Down

0 comments on commit 73b95fb

Please sign in to comment.