git: cb8d7c44d6ac - main - tcp_syncache: add net.inet.tcp.syncache.see_other sysctl

Gleb Smirnoff glebius at FreeBSD.org
Thu Apr 15 22:27:57 UTC 2021


The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=cb8d7c44d6acd4f7f6be7f8b762315260f70d896

commit cb8d7c44d6acd4f7f6be7f8b762315260f70d896
Author:     Gleb Smirnoff <glebius at FreeBSD.org>
AuthorDate: 2021-03-19 07:22:36 +0000
Commit:     Gleb Smirnoff <glebius at FreeBSD.org>
CommitDate: 2021-04-15 22:26:48 +0000

    tcp_syncache: add net.inet.tcp.syncache.see_other sysctl
    
    A security feature from c06f087ccb12 appeared to be a huge bottleneck
    under SYN flood. To mitigate that add a sysctl that would make
    syncache(4) globally visible, ignoring UID/GID, jail(2) and mac(4)
    checks. When turned on, we won't need to call crhold() on the listening
    socket credential for every incoming SYN packet.
    
    Reviewed by:    bz
---
 share/man/man4/syncache.4  | 29 +++++++++++++++++++++++++++--
 sys/netinet/tcp_syncache.c | 10 ++++++++--
 sys/netinet/tcp_syncache.h |  1 +
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/share/man/man4/syncache.4 b/share/man/man4/syncache.4
index b212b12cde95..26ed225bcce8 100644
--- a/share/man/man4/syncache.4
+++ b/share/man/man4/syncache.4
@@ -12,7 +12,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 22, 2008
+.Dd April 12, 2021
 .Dt SYNCACHE 4
 .Os
 .Sh NAME
@@ -39,6 +39,8 @@ MIBs for controlling TCP SYN caching
 .Nm sysctl Cm net.inet.tcp.syncache.rexmtlimit
 .It
 .Nm sysctl Cm net.inet.tcp.syncache.count
+.It
+.Nm sysctl Cm net.inet.tcp.syncache.see_other
 .El
 .Sh DESCRIPTION
 The
@@ -150,6 +152,25 @@ Tunable via
 Number of entries present in the
 .Nm
 (read-only).
+.It Va see_other
+If set to true value, all
+.Nm
+entries will be visible via
+.Va net.inet.tcp.pcblist
+sysctl, or via
+.Xr netstat 1 ,
+ignoring all of
+.Xr security 7
+UID/GID,
+.Xr jail 2
+and
+.Xr mac 4
+checks.
+If turned off, the visibility checks are enforced.
+However, extra
+.Xr ucred 9
+referencing is required on every incoming SYN packet processed.
+The default is off.
 .El
 .Pp
 Statistics on the performance of the
@@ -192,9 +213,13 @@ Connections created from segment containing ACK.
 .El
 .Sh SEE ALSO
 .Xr netstat 1 ,
+.Xr jail 2 ,
+.Xr mac ,
 .Xr tcp 4 ,
+.Xr security 7,
 .Xr loader 8 ,
-.Xr sysctl 8
+.Xr sysctl 8 ,
+.Xr ucred 9
 .Sh HISTORY
 The existing
 .Nm
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 7c6bad415d7d..4cd8411af8d5 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -191,6 +191,11 @@ SYSCTL_UINT(_net_inet_tcp_syncache, OID_AUTO, hashsize, CTLFLAG_VNET | CTLFLAG_R
     &VNET_NAME(tcp_syncache.hashsize), 0,
     "Size of TCP syncache hashtable");
 
+SYSCTL_BOOL(_net_inet_tcp_syncache, OID_AUTO, see_other, CTLFLAG_VNET |
+    CTLFLAG_RW, &VNET_NAME(tcp_syncache.see_other), 0,
+    "All syncache(4) entries are visible, ignoring UID/GID, jail(2) "
+    "and mac(4) checks");
+
 static int
 sysctl_net_inet_tcp_syncache_rexmtlimit_check(SYSCTL_HANDLER_ARGS)
 {
@@ -1409,7 +1414,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	 */
 	KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so));
 	tp = sototcpcb(so);
-	cred = crhold(so->so_cred);
+	cred = V_tcp_syncache.see_other ? NULL : crhold(so->so_cred);
 
 #ifdef INET6
 	if (inc->inc_flags & INC_ISIPV6) {
@@ -2498,7 +2503,8 @@ syncache_pcblist(struct sysctl_req *req)
 		sch = &V_tcp_syncache.hashbase[i];
 		SCH_LOCK(sch);
 		TAILQ_FOREACH(sc, &sch->sch_bucket, sc_hash) {
-			if (cr_cansee(req->td->td_ucred, sc->sc_cred) != 0)
+			if (sc->sc_cred != NULL &&
+			    cr_cansee(req->td->td_ucred, sc->sc_cred) != 0)
 				continue;
 			if (sc->sc_inc.inc_flags & INC_ISIPV6)
 				xt.xt_inp.inp_vflag = INP_IPV6;
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index c56dce55f1c1..03e34a89c112 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -134,6 +134,7 @@ struct tcp_syncache {
 	time_t	pause_until;
 	uint8_t pause_backoff;
 	volatile bool paused;
+	bool see_other;
 };
 
 /* Internal use for the syncookie functions. */


More information about the dev-commits-src-all mailing list