The branch stable/13 has been updated by rew:

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

commit 7205809809e70db0abf2cecaf7f5e056650315bb
Author:     Robert Wing <[email protected]>
AuthorDate: 2022-01-09 01:07:50 +0000
Commit:     Robert Wing <[email protected]>
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.

Reply via email to