aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2026-07-06 21:30:41 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2026-07-06 21:30:41 +0000
commitee5d87a3e2ca1c169ca2032fcb12841a499356c9 (patch)
treeb619b1724eacac1d0c73e9e2b4073474b6c14ee2
parent4dd9e4ed9771630388cdf49ba3bcd1a608b05c9c (diff)
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
-rw-r--r--sys/netinet/raw_ip.c3
1 files changed, 1 insertions, 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;