From: Alexander Bluhm Subject: Re: tcp, sysctl: unlock TCPCTL_ROOTONLY and TCPCTL_BADDYNAMIC To: Vitaliy Makkoveev Cc: tech@openbsd.org Date: Mon, 12 May 2025 21:36:17 +0200 On Sun, May 11, 2025 at 01:15:08PM +0300, Vitaliy Makkoveev wrote: > The copy-paste from udp_sysctl(). It is not yet clean, is it reasonable > to combine this code with udp. One might consider adding a in_pcbsysctl() function. But I think complexity is not worth it. Just copy the code from udp to tcp. > 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); >