Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
socreate() shared net lock
To:
tech@openbsd.org
Date:
Wed, 5 Feb 2025 18:58:07 +0100

Download raw body.

Thread
Hi,

socreate() and its internet attach functions look MP safe.  So
replace exclusive net lock with shared net lock plus socket lock.

As sofree() unlocks exclusive net lock, swap the locks in the error
path.  As neither userland not protocol stack know about the newly
created socket, this is safe.

ok?

bluhm

Index: kern/uipc_socket.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
diff -u -p -r1.371 uipc_socket.c
--- kern/uipc_socket.c	5 Feb 2025 08:28:25 -0000	1.371
+++ kern/uipc_socket.c	5 Feb 2025 13:30:16 -0000
@@ -208,15 +208,19 @@ socreate(int dom, struct socket **aso, i
 	so->so_snd.sb_timeo_nsecs = INFSLP;
 	so->so_rcv.sb_timeo_nsecs = INFSLP;
 
-	solock(so);
+	solock_shared(so);
 	error = pru_attach(so, proto, M_WAIT);
 	if (error) {
+		if (!solock_persocket(so)) {
+			sounlock_shared(so);
+			solock(so);
+		}
 		so->so_state |= SS_NOFDREF;
 		/* sofree() calls sounlock(). */
 		sofree(so, 0);
 		return (error);
 	}
-	sounlock(so);
+	sounlock_shared(so);
 	*aso = so;
 	return (0);
 }
Index: netinet/raw_ip.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/raw_ip.c,v
diff -u -p -r1.163 raw_ip.c
--- netinet/raw_ip.c	1 Jan 2025 13:44:22 -0000	1.163
+++ netinet/raw_ip.c	5 Feb 2025 13:28:03 -0000
@@ -488,7 +488,6 @@ rip_attach(struct socket *so, int proto,
 
 	if ((error = soreserve(so, rip_sendspace, rip_recvspace)))
 		return error;
-	NET_ASSERT_LOCKED();
 	if ((error = in_pcballoc(so, &rawcbtable, wait)))
 		return error;
 	inp = sotoinpcb(so);
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v
diff -u -p -r1.241 tcp_usrreq.c
--- netinet/tcp_usrreq.c	30 Jan 2025 14:40:50 -0000	1.241
+++ netinet/tcp_usrreq.c	5 Feb 2025 13:28:03 -0000
@@ -487,7 +487,6 @@ tcp_attach(struct socket *so, int proto,
 			return (error);
 	}
 
-	NET_ASSERT_LOCKED();
 #ifdef INET6
 	if (so->so_proto->pr_domain->dom_family == PF_INET6)
 		table = &tcb6table;
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
diff -u -p -r1.330 udp_usrreq.c
--- netinet/udp_usrreq.c	25 Jan 2025 02:06:40 -0000	1.330
+++ netinet/udp_usrreq.c	5 Feb 2025 13:28:03 -0000
@@ -1107,7 +1107,6 @@ udp_attach(struct socket *so, int proto,
 	    atomic_load_int(&udp_recvspace))))
 		return error;
 
-	NET_ASSERT_LOCKED();
 #ifdef INET6
 	if (so->so_proto->pr_domain->dom_family == PF_INET6)
 		table = &udb6table;
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
diff -u -p -r1.186 raw_ip6.c
--- netinet6/raw_ip6.c	8 Nov 2024 10:24:13 -0000	1.186
+++ netinet6/raw_ip6.c	5 Feb 2025 13:28:03 -0000
@@ -606,7 +606,6 @@ rip6_attach(struct socket *so, int proto
 
 	if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)))
 		return error;
-	NET_ASSERT_LOCKED();
 	if ((error = in_pcballoc(so, &rawin6pcbtable, wait)))
 		return error;