From 8555e51e3db8c3e12459dddbfa6e478b93e55bc3 Mon Sep 17 00:00:00 2001 From: Vitaliy Makkoveev Date: Tue, 7 Dec 2021 01:19:48 +0000 Subject: Make `unp_msgcount' and `unp_file' protection with `unp_gc_lock' rwlock(9). This save us from from races provided by unlocked access to the `f_count' which cause false marking alive socket as dead. We always modify `f_count' and `unp_msgcount' together so the `f_count' modification should also pass the `unp_gc_rwlock' before `unp_msgcount' increment and after `unp_msgcount' decrement. The locked `unp_file' assignment avoids us from drain unp_gc() run. This moves unp_gc() locking back when these wariables were protected with the same lock which was taken for all garbage collector run but uses another lock not `unp_lock'. ok kettenis@ bluhm@ --- sys/kern/uipc_usrreq.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 1c0a4454458..7cb3cc39494 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.158 2021/11/17 22:56:19 mvs Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.159 2021/12/07 01:19:47 mvs Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -960,8 +960,11 @@ restart: fp = rp->fp; rp++; - if ((unp = fptounp(fp)) != NULL) - atomic_dec_long(&unp->unp_msgcount); + if ((unp = fptounp(fp)) != NULL) { + rw_enter_write(&unp_gc_lock); + unp->unp_msgcount--; + rw_exit_write(&unp_gc_lock); + } } mtx_enter(&unp_rights_mtx); @@ -1085,8 +1088,10 @@ morespace: rp->flags = fdp->fd_ofileflags[fd] & UF_PLEDGED; rp--; if ((unp = fptounp(fp)) != NULL) { - atomic_inc_long(&unp->unp_msgcount); + rw_enter_write(&unp_gc_lock); + unp->unp_msgcount++; unp->unp_file = fp; + rw_exit_write(&unp_gc_lock); } } fdpunlock(fdp); @@ -1099,8 +1104,11 @@ fail: for ( ; i > 0; i--) { rp++; fp = rp->fp; - if ((unp = fptounp(fp)) != NULL) - atomic_dec_long(&unp->unp_msgcount); + if ((unp = fptounp(fp)) != NULL) { + rw_enter_write(&unp_gc_lock); + unp->unp_msgcount--; + rw_exit_write(&unp_gc_lock); + } FRELE(fp, p); } @@ -1136,8 +1144,11 @@ unp_gc(void *arg __unused) fp = defer->ud_fp[i].fp; if (fp == NULL) continue; - if ((unp = fptounp(fp)) != NULL) - atomic_dec_long(&unp->unp_msgcount); + if ((unp = fptounp(fp)) != NULL) { + rw_enter_write(&unp_gc_lock); + unp->unp_msgcount--; + rw_exit_write(&unp_gc_lock); + } mtx_enter(&unp_rights_mtx); unp_rights--; mtx_leave(&unp_rights_mtx); -- cgit v1.2.3