From ce1ab8dd6b189cef03d158b4f8bc01c47d968db8 Mon Sep 17 00:00:00 2001 From: gnezdo Date: Wed, 31 Aug 2022 09:07:35 +0000 Subject: [PATCH] Lock vmobjlock then check u_flags & UVM_VNODE_VALID in uvn_attach This is a continuation of this commit: "Always acquire the `vmobjlock' before incrementing an object's reference." Unfortuantely this created a race found by syzkaller manifesting as: panic: kernel diagnostic assertion "uvn->u_obj.uo_refs == 0" failed: file "sys/uvm/uvm_vnode.c", line 234 ok mpi@ Reported-by: syzbot+dd2d2684ad2818c927da@syzkaller.appspotmail.com --- sys/uvm/uvm_vnode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index 8c1657cbe86..28e51a2c96e 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_vnode.c,v 1.126 2022/08/01 14:15:46 mpi Exp $ */ +/* $OpenBSD: uvm_vnode.c,v 1.127 2022/08/31 09:07:35 gnezdo Exp $ */ /* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */ /* @@ -161,9 +161,9 @@ uvn_attach(struct vnode *vp, vm_prot_t accessprot) * we can bump the reference count, check to see if we need to * add it to the writeable list, and then return. */ + rw_enter(uvn->u_obj.vmobjlock, RW_WRITE); if (uvn->u_flags & UVM_VNODE_VALID) { /* already active? */ - rw_enter(uvn->u_obj.vmobjlock, RW_WRITE); /* regain vref if we were persisting */ if (uvn->u_obj.uo_refs == 0) { vref(vp); @@ -181,6 +181,7 @@ uvn_attach(struct vnode *vp, vm_prot_t accessprot) return (&uvn->u_obj); } + rw_exit(uvn->u_obj.vmobjlock); /* * need to call VOP_GETATTR() to get the attributes, but that could -- 2.20.1