From: Vitaliy Makkoveev Subject: tcp, sysctl: unlock TCPCTL_ROOTONLY and TCPCTL_BADDYNAMIC To: Alexander Bluhm , tech@openbsd.org Date: Sun, 11 May 2025 13:15:08 +0300 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);