From 68a7a9edc502eda8af057e199e2a3b5c5844b5c7 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 28 Oct 2021 11:58:57 -0400 Subject: [PATCH] Fix potential use-after-frees in FreeBSD getpages and setattr VOPs The objset object is reallocated during certain dataset operations, such as rollbacks, so the objset pointer must be loaded after acquiring the teardown lock. Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Mark Johnston Closes #12704 --- module/os/freebsd/zfs/zfs_vnops_os.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index e4a15e6d9ea..322d64f01f1 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -2208,7 +2208,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) { vnode_t *vp = ZTOV(zp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; - objset_t *os = zfsvfs->z_os; + objset_t *os; zilog_t *zilog; dmu_tx_t *tx; vattr_t oldva; @@ -2243,6 +2243,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); + os = zfsvfs->z_os; zilog = zfsvfs->z_log; /* @@ -4046,7 +4047,6 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind, { znode_t *zp = VTOZ(vp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; - objset_t *os = zp->z_zfsvfs->z_os; zfs_locked_range_t *lr; vm_object_t object; off_t start, end, obj_size; @@ -4116,8 +4116,8 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind, * ZFS will panic if we request DMU to read beyond the end of the last * allocated block. */ - error = dmu_read_pages(os, zp->z_id, ma, count, &pgsin_b, &pgsin_a, - MIN(end, obj_size) - (end - PAGE_SIZE)); + error = dmu_read_pages(zfsvfs->z_os, zp->z_id, ma, count, &pgsin_b, + &pgsin_a, MIN(end, obj_size) - (end - PAGE_SIZE)); if (lr != NULL) zfs_rangelock_exit(lr);