diff options
author | Mark Johnston <[email protected]> | 2021-10-28 11:58:57 -0400 |
---|---|---|
committer | Tony Hutter <[email protected]> | 2021-12-13 13:22:34 -0800 |
commit | 07165ce540323bc80b7e25372ca60ac21a16b7f1 (patch) | |
tree | 67fb5cb990690223c554a481526baa80c4f405a5 /module | |
parent | 6ed7d77b44b643e0755828b86e48bd2826df620f (diff) |
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 <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Mark Johnston <[email protected]>
Closes #12704
Diffstat (limited to 'module')
-rw-r--r-- | module/os/freebsd/zfs/zfs_vnops_os.c | 8 |
1 files 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 7aeb6ca3f..2c225c453 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -2222,7 +2222,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; @@ -2257,6 +2257,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; /* @@ -4060,7 +4061,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; @@ -4130,8 +4130,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); |