From 770fa7db6c9e3f86bf07c5439a0649a3de982aa9 Mon Sep 17 00:00:00 2001 From: Axel Gembe Date: Fri, 13 Oct 2023 18:20:08 +0700 Subject: [PATCH] Fix use-after-free after unmount 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 --- module/os/windows/zfs/zfs_vnops_windows.c | 5 +++++ module/os/windows/zfs/zfs_vnops_windows_mount.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/module/os/windows/zfs/zfs_vnops_windows.c b/module/os/windows/zfs/zfs_vnops_windows.c index 349dfa1a844c..04736e2b0d2f 100644 --- a/module/os/windows/zfs/zfs_vnops_windows.c +++ b/module/os/windows/zfs/zfs_vnops_windows.c @@ -132,6 +132,11 @@ zfs_AcquireForLazyWrite(void *Context, BOOLEAN Wait) struct vnode *vp = fo->FsContext; dprintf("%s:fo %p\n", __func__, fo); + if (zfsvfs == NULL) { + dprintf("%s:fo already freed zfsvfs\n", __func__); + return (FALSE); + } + /* Confirm we are mounted, and stop unmounting */ if (vfs_busy(zfsvfs->z_vfs, 0) != 0) return (FALSE); diff --git a/module/os/windows/zfs/zfs_vnops_windows_mount.c b/module/os/windows/zfs/zfs_vnops_windows_mount.c index 4673a8fbfedf..1aabdbf87a04 100644 --- a/module/os/windows/zfs/zfs_vnops_windows_mount.c +++ b/module/os/windows/zfs/zfs_vnops_windows_mount.c @@ -1583,6 +1583,12 @@ zfs_windows_unmount(zfs_cmd_t *zc) if (error) goto out_unlock; + if (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);