git: ee5d87a3e2ca - main - raw ip: fix race of two connect(2)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Mon, 06 Jul 2026 21:38:37 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=ee5d87a3e2ca1c169ca2032fcb12841a499356c9

commit ee5d87a3e2ca1c169ca2032fcb12841a499356c9
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2026-07-06 21:30:41 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2026-07-06 21:30:41 +0000

    raw ip: fix race of two connect(2)
    
    The historical design of sockets is that on a re-connect the disconnect is
    performed at the socket layer in soconnectat().  Since SMP times this is
    known to be racy and the function has appopriate comment.  I missed that
    in the recent change.  The pr_connect method should normally expect the
    socket to be already disconnected, however should be able to handle a race
    where socket is actually connected.  Convert the check that incorrectly
    tried to handle normal path of re-connect into check that handles the
    race.
    
    Reported by:    markj
    Fixes:  ece716c5d34728a170f1dfe1b3389c267d6ddd1e
---
 sys/netinet/raw_ip.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 851f70cbb0ad..67e798ccad54 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -904,8 +904,7 @@ rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 	KASSERT(inp != NULL, ("rip_connect: inp == NULL"));
 
 	INP_WLOCK(inp);
-	if (inp->inp_faddr.s_addr != INADDR_ANY &&
-	    addr->sin_addr.s_addr == INADDR_ANY)
+	if (__predict_false(inp->inp_faddr.s_addr != INADDR_ANY))
 		rip_dodisconnect(inp, false);
 	if (addr->sin_addr.s_addr != INADDR_ANY) {
 		inp->inp_faddr = addr->sin_addr;