git: 7205809809e7 - stable/13 - syncache: accept packet with no SA when TCP_MD5SIG is set
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 10 Feb 2022 19:33:29 UTC
The branch stable/13 has been updated by rew:
URL: https://cgit.FreeBSD.org/src/commit/?id=7205809809e70db0abf2cecaf7f5e056650315bb
commit 7205809809e70db0abf2cecaf7f5e056650315bb
Author: Robert Wing <rew@FreeBSD.org>
AuthorDate: 2022-01-09 01:07:50 +0000
Commit: Robert Wing <rew@FreeBSD.org>
CommitDate: 2022-02-10 19:31:33 +0000
syncache: accept packet with no SA when TCP_MD5SIG is set
When TCP_MD5SIG is set on a socket, all packets are dropped that don't
contain an MD5 signature. Relax this behavior to accept a non-signed
packet when a security association doesn't exist with the peer.
This is useful when a listen socket set with TCP_MD5SIG wants to handle
connections protected with and without MD5 signatures.
Reviewed by: bz (previous version)
Sponsored by: nepustil.net
Sponsored by: Klara Inc.
Differential Revision: https://reviews.freebsd.org/D33227
(cherry picked from commit eb18708ec8c7e1de6a05aba41971659549991b10)
---
share/man/man4/tcp.4 | 6 +++++-
sys/netinet/tcp_syncache.c | 30 ++++++++++++++++++------------
sys/netipsec/xform_tcp.c | 5 +++++
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4
index e49df5319efb..3fe2753bf408 100644
--- a/share/man/man4/tcp.4
+++ b/share/man/man4/tcp.4
@@ -34,7 +34,7 @@
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd June 27, 2021
+.Dd January 8, 2022
.Dt TCP 4
.Os
.Sh NAME
@@ -339,6 +339,10 @@ This entry can only be specified on a per-host basis at this time.
.Pp
If an SADB entry cannot be found for the destination,
the system does not send any outgoing segments and drops any inbound segments.
+However, during connection negotiation, a non-signed segment will be accepted if
+an SADB entry does not exist between hosts.
+When a non-signed segment is accepted, the established connection is not
+protected with MD5 digests.
.It Dv TCP_STATS
Manage collection of connection level statistics using the
.Xr stats 3
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index a1102574b325..e7fb8da52216 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1513,19 +1513,25 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
/*
- * If listening socket requested TCP digests, check that received
- * SYN has signature and it is correct. If signature doesn't match
- * or TCP_SIGNATURE support isn't enabled, drop the packet.
+ * When the socket is TCP-MD5 enabled check that,
+ * - a signed packet is valid
+ * - a non-signed packet does not have a security association
+ *
+ * If a signed packet fails validation or a non-signed packet has a
+ * security association, the packet will be dropped.
*/
if (ltflags & TF_SIGNATURE) {
- if ((to->to_flags & TOF_SIGNATURE) == 0) {
- TCPSTAT_INC(tcps_sig_err_nosigopt);
- goto done;
+ if (to->to_flags & TOF_SIGNATURE) {
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to->to_signature) != 0)
+ goto done;
+ } else {
+ if (TCPMD5_ENABLED() &&
+ TCPMD5_INPUT(m, NULL, NULL) != ENOENT)
+ goto done;
}
- if (!TCPMD5_ENABLED() ||
- TCPMD5_INPUT(m, th, to->to_signature) != 0)
- goto done;
- }
+ } else if (to->to_flags & TOF_SIGNATURE)
+ goto done;
#endif /* TCP_SIGNATURE */
/*
* See if we already have an entry for this connection.
@@ -1723,11 +1729,11 @@ skip_alloc:
}
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
/*
- * If listening socket requested TCP digests, flag this in the
+ * If incoming packet has an MD5 signature, flag this in the
* syncache so that syncache_respond() will do the right thing
* with the SYN+ACK.
*/
- if (ltflags & TF_SIGNATURE)
+ if (to->to_flags & TOF_SIGNATURE)
sc->sc_flags |= SCF_SIGNATURE;
#endif /* TCP_SIGNATURE */
if (to->to_flags & TOF_SACKPERM)
diff --git a/sys/netipsec/xform_tcp.c b/sys/netipsec/xform_tcp.c
index b53544cd00fb..ce2552f0a205 100644
--- a/sys/netipsec/xform_tcp.c
+++ b/sys/netipsec/xform_tcp.c
@@ -269,6 +269,11 @@ tcp_ipsec_input(struct mbuf *m, struct tcphdr *th, u_char *buf)
KMOD_TCPSTAT_INC(tcps_sig_err_buildsig);
return (ENOENT);
}
+ if (buf == NULL) {
+ key_freesav(&sav);
+ KMOD_TCPSTAT_INC(tcps_sig_err_nosigopt);
+ return (EACCES);
+ }
/*
* tcp_input() operates with TCP header fields in host
* byte order. We expect them in network byte order.