summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2016-01-19 10:41:21 -0800
committerBrian Behlendorf <[email protected]>2016-01-20 13:36:15 -0800
commit37c56346cca55f60e36bb584e00966bba24af327 (patch)
treec23fa154836ab6fc9e4deb74468b442a4095fd67
parentae3a373566042ad086b51dce66059c8cae321faf (diff)
Close possible zfs_znode_held() race
Check if the lock is held while holding the z_hold_locks() lock. This prevents a possible use-after-free bug for callers which are not holding the lock. There currently are no such callers so this can't cause a problem today but it has been fixed regardless. Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #4244 Issue #4124
-rw-r--r--module/zfs/zfs_znode.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c
index 03274a9b9..e4bd62fd2 100644
--- a/module/zfs/zfs_znode.c
+++ b/module/zfs/zfs_znode.c
@@ -248,17 +248,16 @@ zfs_znode_held(zfs_sb_t *zsb, uint64_t obj)
{
znode_hold_t *zh, search;
int i = ZFS_OBJ_HASH(zsb, obj);
+ boolean_t held;
search.zh_obj = obj;
mutex_enter(&zsb->z_hold_locks[i]);
zh = avl_find(&zsb->z_hold_trees[i], &search, NULL);
+ held = (zh && MUTEX_HELD(&zh->zh_lock)) ? B_TRUE : B_FALSE;
mutex_exit(&zsb->z_hold_locks[i]);
- if (zh && MUTEX_HELD(&zh->zh_lock))
- return (B_TRUE);
-
- return (B_FALSE);
+ return (held);
}
static znode_hold_t *