aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-02-12 14:00:43 +0000
committerMark Johnston <markj@FreeBSD.org>2026-02-12 14:00:43 +0000
commit7c1c0e94363db09af0c260d9292160cdd2230f23 (patch)
tree775852b1dc60cb534cbdd3306d90e7ce3253ecb3
parentbe393b6f0497f374c679c31e746705515eb9a554 (diff)
rpc: Improve socket locking in svc_vc_accept()
so_state modifications must be synchronized by the socket lock. For the listening socket this probably doesn't matter but for the child socket I think it's possible that this unlocked update clobbers a state transition if the nascent connection is being disconnected for some reason. Also fix the line which potentially clears SS_NBIO in the listening socket. It is unclear whether this code is used at all. Reviewed by: glebius MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D55247
-rw-r--r--sys/rpc/svc_vc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 7e30582c59e0..848109704ad0 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -389,12 +389,15 @@ svc_vc_accept(struct socket *head, struct socket **sop)
SOLISTEN_LOCK(head);
nbio = head->so_state & SS_NBIO;
head->so_state |= SS_NBIO;
- error = solisten_dequeue(head, &so, 0);
- head->so_state &= (nbio & ~SS_NBIO);
+ error = solisten_dequeue(head, &so, nbio ? SOCK_NONBLOCK : 0);
+ if (nbio == 0) {
+ SOLISTEN_LOCK(head);
+ head->so_state &= ~SS_NBIO;
+ SOLISTEN_UNLOCK(head);
+ }
if (error)
goto done;
- so->so_state |= nbio;
*sop = so;
/* connection has been removed from the listen queue */