Download raw body.
tcp, sysctl: unlock TCPCTL_ROOTONLY and TCPCTL_BADDYNAMIC
The copy-paste from udp_sysctl(). It is not yet clean, is it reasonable
to combine this code with udp.
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.245
diff -u -p -r1.245 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c 10 Mar 2025 15:11:46 -0000 1.245
+++ sys/netinet/tcp_usrreq.c 12 May 2025 18:34:34 -0000
@@ -1419,22 +1419,40 @@ tcp_sysctl(int *name, u_int namelen, voi
return (ENOTDIR);
switch (name[0]) {
- case TCPCTL_BADDYNAMIC:
- NET_LOCK();
- error = sysctl_struct(oldp, oldlenp, newp, newlen,
- baddynamicports.tcp, sizeof(baddynamicports.tcp));
- NET_UNLOCK();
- return (error);
-
case TCPCTL_ROOTONLY:
- if (newp && securelevel > 0)
+ if (newp && (int)atomic_load_int(&securelevel) > 0)
return (EPERM);
- NET_LOCK();
+ /* FALLTHROUGH */
+ case TCPCTL_BADDYNAMIC: {
+ struct baddynamicports *ports = (name[0] == TCPCTL_ROOTONLY ?
+ &rootonlyports : &baddynamicports);
+ const size_t bufitems = DP_MAPSIZE;
+ const size_t buflen = bufitems * sizeof(uint32_t);
+ size_t i;
+ uint32_t *buf;
+ int error;
+
+ buf = malloc(buflen, M_SYSCTL, M_WAITOK | M_ZERO);
+
+ NET_LOCK_SHARED();
+ for (i = 0; i < bufitems; ++i)
+ buf[i] = ports->tcp[i];
+ NET_UNLOCK_SHARED();
+
error = sysctl_struct(oldp, oldlenp, newp, newlen,
- rootonlyports.tcp, sizeof(rootonlyports.tcp));
- NET_UNLOCK();
- return (error);
+ buf, buflen);
+
+ if (error == 0 && newp) {
+ NET_LOCK();
+ for (i = 0; i < bufitems; ++i)
+ ports->tcp[i] = buf[i];
+ NET_UNLOCK();
+ }
+ free(buf, M_SYSCTL, buflen);
+
+ return (error);
+ }
case TCPCTL_IDENT:
return tcp_ident(oldp, oldlenp, newp, newlen, 0);
tcp, sysctl: unlock TCPCTL_ROOTONLY and TCPCTL_BADDYNAMIC