Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
sysctl_source(): move copyout(9) out of netlock
To:
Alexander Bluhm <bluhm@openbsd.org>, tech@openbsd.org
Date:
Thu, 23 Jan 2025 20:15:25 +0300

Download raw body.

Thread
Netlock required only to store data to local variable, the rest could be
done lockless. sysctl_source() is local to net/rtsock.c.

Index: sys/net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.377
diff -u -p -r1.377 rtsock.c
--- sys/net/rtsock.c	9 Jan 2025 18:20:29 -0000	1.377
+++ sys/net/rtsock.c	23 Jan 2025 17:07:28 -0000
@@ -2136,12 +2136,17 @@ sysctl_ifnames(struct walkarg *w)
 int
 sysctl_source(int af, u_int tableid, struct walkarg *w)
 {
-	struct sockaddr	*sa;
+	struct sockaddr	 sa;
+	struct sockaddr	*sa_tmp;
 	int		 size, error = 0;
 
-	sa = rtable_getsource(tableid, af);
-	if (sa) {
-		switch (sa->sa_family) {
+	NET_LOCK_SHARED();
+	if ((sa_tmp = rtable_getsource(tableid, af)) != NULL)
+		sa = *sa_tmp;
+	NET_UNLOCK_SHARED();
+
+	if (sa_tmp) {
+		switch (sa.sa_family) {
 		case AF_INET:
 			size = sizeof(struct sockaddr_in);
 			break;
@@ -2155,7 +2160,7 @@ sysctl_source(int af, u_int tableid, str
 		}
 		w->w_needed += size;
 		if (w->w_where && w->w_needed <= w->w_given) {
-			if ((error = copyout(sa, w->w_where, size)))
+			if ((error = copyout(&sa, w->w_where, size)))
 				return (error);
 			w->w_where += size;
 		}
@@ -2236,7 +2241,6 @@ sysctl_rtable(int *name, u_int namelen, 
 		tableid = w.w_arg;
 		if (!rtable_exists(tableid))
 			return (ENOENT);
-		NET_LOCK_SHARED();
 		for (i = 1; i <= AF_MAX; i++) {
 			if (af != 0 && af != i)
 				continue;
@@ -2247,7 +2251,6 @@ sysctl_rtable(int *name, u_int namelen, 
 			if (error)
 				break;
 		}
-		NET_UNLOCK_SHARED();
 		break;
 	}
 	free(w.w_tmem, M_RTABLE, w.w_tmemsize);