Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
unlock netlock before socket lock
To:
tech@openbsd.org
Date:
Fri, 13 Jun 2025 17:07:28 +0200

Download raw body.

Thread
  • Alexander Bluhm:

    unlock netlock before socket lock

Hi,

While testing my diff that uses soclose() with shared netlock, I
noticed a crash in sounlock_shared().  After releasing the socket
lock, the family of the socket is inspected.  It should be the other
way around.

Currently exclusive netlock protects us, but I want to remove this
netlock gradually.

ok?

bluhm

Index: kern/uipc_socket2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
diff -u -p -r1.185 uipc_socket2.c
--- kern/uipc_socket2.c	12 Mar 2025 14:08:31 -0000	1.185
+++ kern/uipc_socket2.c	13 Jun 2025 14:52:26 -0000
@@ -409,13 +409,13 @@ sounlock(struct socket *so)
 void
 sounlock_shared(struct socket *so)
 {
-	rw_exit_write(&so->so_lock);
 	switch (so->so_proto->pr_domain->dom_family) {
 	case PF_INET:
 	case PF_INET6:
 		NET_UNLOCK_SHARED();
 		break;
 	}
+	rw_exit_write(&so->so_lock);
 }
 
 void
@@ -427,6 +427,12 @@ sounlock_nonet(struct socket *so)
 void
 sounlock_pair(struct socket *so1, struct socket *so2)
 {
+	switch (so1->so_proto->pr_domain->dom_family) {
+	case PF_INET:
+	case PF_INET6:
+		NET_UNLOCK_SHARED();
+		break;
+	}
 	if (so1 == so2)
 		rw_exit_write(&so1->so_lock);
 	else if (so1 < so2) {
@@ -435,12 +441,6 @@ sounlock_pair(struct socket *so1, struct
 	} else {
 		rw_exit_write(&so1->so_lock);
 		rw_exit_write(&so2->so_lock);
-	}
-	switch (so1->so_proto->pr_domain->dom_family) {
-	case PF_INET:
-	case PF_INET6:
-		NET_UNLOCK_SHARED();
-		break;
 	}
 }