Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
tcp, sysctl: unlock TCPCTL_ROOTONLY and TCPCTL_BADDYNAMIC
To:
Alexander Bluhm <bluhm@openbsd.org>, tech@openbsd.org
Date:
Sun, 11 May 2025 13:15:08 +0300

Download raw body.

Thread
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);