From: Vitaliy Makkoveev Subject: sysctl_source(): move copyout(9) out of netlock To: Alexander Bluhm , tech@openbsd.org Date: Thu, 23 Jan 2025 20:15:25 +0300 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);