aboutsummaryrefslogtreecommitdiffstats
path: root/module/os/linux/zfs/zfs_znode.c
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2023-01-19 16:59:05 -0800
committerGitHub <[email protected]>2023-01-19 16:59:05 -0800
commitc6dab6dd39214d587c7013e8c6dfeb085e3eb41c (patch)
treec0ec00fc4945800b7b8103d2abb3a42a26e9763e /module/os/linux/zfs/zfs_znode.c
parenta379083d9f2bb9dd80f4636e593bcb2c1d94d11b (diff)
Fix unprotected zfs_znode_dmu_fini
In original code, zfs_znode_dmu_fini is called in zfs_rmnode without zfs_znode_hold_enter. It seems to assume it's ok to do so when the znode is unlinked. However this assumption is not correct, as zfs_zget can be called by NFS through zpl_fh_to_dentry as pointed out by Christian in https://github.com/openzfs/zfs/pull/12767, which could result in a use-after-free bug. Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Ryan Moeller <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes #12767 Closes #14364
Diffstat (limited to 'module/os/linux/zfs/zfs_znode.c')
-rw-r--r--module/os/linux/zfs/zfs_znode.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c
index 395e2cf57..1faf25d93 100644
--- a/module/os/linux/zfs/zfs_znode.c
+++ b/module/os/linux/zfs/zfs_znode.c
@@ -271,7 +271,7 @@ zfs_znode_held(zfsvfs_t *zfsvfs, uint64_t obj)
return (held);
}
-static znode_hold_t *
+znode_hold_t *
zfs_znode_hold_enter(zfsvfs_t *zfsvfs, uint64_t obj)
{
znode_hold_t *zh, *zh_new, search;
@@ -304,7 +304,7 @@ zfs_znode_hold_enter(zfsvfs_t *zfsvfs, uint64_t obj)
return (zh);
}
-static void
+void
zfs_znode_hold_exit(zfsvfs_t *zfsvfs, znode_hold_t *zh)
{
int i = ZFS_OBJ_HASH(zfsvfs, zh->zh_obj);
@@ -357,7 +357,7 @@ zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp,
void
zfs_znode_dmu_fini(znode_t *zp)
{
- ASSERT(zfs_znode_held(ZTOZSB(zp), zp->z_id) || zp->z_unlinked ||
+ ASSERT(zfs_znode_held(ZTOZSB(zp), zp->z_id) ||
RW_WRITE_HELD(&ZTOZSB(zp)->z_teardown_inactive_lock));
sa_handle_destroy(zp->z_sa_hdl);