Download raw body.
socreate() shared net lock
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;
socreate() shared net lock