From owner-svn-src-stable-11@freebsd.org Mon Aug 28 10:02:49 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 57B73E0A6D3; Mon, 28 Aug 2017 10:02:49 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 32CD571011; Mon, 28 Aug 2017 10:02:49 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7SA2mbU071032; Mon, 28 Aug 2017 10:02:48 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7SA2lXu071028; Mon, 28 Aug 2017 10:02:48 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201708281002.v7SA2lXu071028@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Mon, 28 Aug 2017 10:02:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r322966 - stable/11/sys/netipsec X-SVN-Group: stable-11 X-SVN-Commit-Author: ae X-SVN-Commit-Paths: stable/11/sys/netipsec X-SVN-Commit-Revision: 322966 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Aug 2017 10:02:49 -0000 Author: ae Date: Mon Aug 28 10:02:47 2017 New Revision: 322966 URL: https://svnweb.freebsd.org/changeset/base/322966 Log: MFC r322750: Fix the regression introduced in r275710. When a security policy should match TCP connection with specific ports, the SYN+ACK segment send by syncache_respond() is considered as forwarded packet, because at this moment TCP connection does not have PCB structure, and ip_output() is called without inpcb pointer. In this case SPIDX filled for SP lookup will not contain TCP ports and security policy will not be found. This can lead to unencrypted SYN+ACK on the wire. This patch restores the old behavior, when ports will not be filled only for forwarded packets. Reported by: Dewayne Geraghty MFC r322751: Remove stale comments. Modified: stable/11/sys/netipsec/ipsec.c stable/11/sys/netipsec/ipsec.h stable/11/sys/netipsec/ipsec6.h stable/11/sys/netipsec/ipsec_output.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netipsec/ipsec.c ============================================================================== --- stable/11/sys/netipsec/ipsec.c Mon Aug 28 09:35:17 2017 (r322965) +++ stable/11/sys/netipsec/ipsec.c Mon Aug 28 10:02:47 2017 (r322966) @@ -563,7 +563,8 @@ ipsec4_setspidx_ipaddr(const struct mbuf *m, struct se } static struct secpolicy * -ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) +ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir, + int needport) { struct secpolicyindex spidx; struct secpolicy *sp; @@ -572,8 +573,7 @@ ipsec4_getpolicy(const struct mbuf *m, struct inpcb *i if (sp == NULL && key_havesp(dir)) { /* Make an index to look for a policy. */ ipsec4_setspidx_ipaddr(m, &spidx); - /* Fill ports in spidx if we have inpcb. */ - ipsec4_get_ulp(m, &spidx, inp != NULL); + ipsec4_get_ulp(m, &spidx, needport); spidx.dir = dir; sp = key_allocsp(&spidx, dir); } @@ -586,12 +586,13 @@ ipsec4_getpolicy(const struct mbuf *m, struct inpcb *i * Check security policy for *OUTBOUND* IPv4 packet. */ struct secpolicy * -ipsec4_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error) +ipsec4_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error, + int needport) { struct secpolicy *sp; *error = 0; - sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_OUTBOUND); + sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_OUTBOUND, needport); if (sp != NULL) sp = ipsec_checkpolicy(sp, inp, error); if (sp == NULL) { @@ -623,7 +624,7 @@ ipsec4_in_reject(const struct mbuf *m, struct inpcb *i struct secpolicy *sp; int result; - sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_INBOUND); + sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_INBOUND, 0); result = ipsec_in_reject(sp, inp, m); key_freesp(&sp); if (result != 0) @@ -731,7 +732,8 @@ ipsec6_setspidx_ipaddr(const struct mbuf *m, struct se } static struct secpolicy * -ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) +ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir, + int needport) { struct secpolicyindex spidx; struct secpolicy *sp; @@ -740,8 +742,7 @@ ipsec6_getpolicy(const struct mbuf *m, struct inpcb *i if (sp == NULL && key_havesp(dir)) { /* Make an index to look for a policy. */ ipsec6_setspidx_ipaddr(m, &spidx); - /* Fill ports in spidx if we have inpcb. */ - ipsec6_get_ulp(m, &spidx, inp != NULL); + ipsec6_get_ulp(m, &spidx, needport); spidx.dir = dir; sp = key_allocsp(&spidx, dir); } @@ -754,12 +755,13 @@ ipsec6_getpolicy(const struct mbuf *m, struct inpcb *i * Check security policy for *OUTBOUND* IPv6 packet. */ struct secpolicy * -ipsec6_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error) +ipsec6_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error, + int needport) { struct secpolicy *sp; *error = 0; - sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_OUTBOUND); + sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_OUTBOUND, needport); if (sp != NULL) sp = ipsec_checkpolicy(sp, inp, error); if (sp == NULL) { @@ -791,7 +793,7 @@ ipsec6_in_reject(const struct mbuf *m, struct inpcb *i struct secpolicy *sp; int result; - sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_INBOUND); + sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_INBOUND, 0); result = ipsec_in_reject(sp, inp, m); key_freesp(&sp); if (result) Modified: stable/11/sys/netipsec/ipsec.h ============================================================================== --- stable/11/sys/netipsec/ipsec.h Mon Aug 28 09:35:17 2017 (r322965) +++ stable/11/sys/netipsec/ipsec.h Mon Aug 28 10:02:47 2017 (r322966) @@ -320,7 +320,7 @@ int ipsec_if_input(struct mbuf *, struct secasvar *, u struct ipsecrequest *ipsec_newisr(void); void ipsec_delisr(struct ipsecrequest *); struct secpolicy *ipsec4_checkpolicy(const struct mbuf *, struct inpcb *, - int *); + int *, int); u_int ipsec_get_reqlevel(struct secpolicy *, u_int); Modified: stable/11/sys/netipsec/ipsec6.h ============================================================================== --- stable/11/sys/netipsec/ipsec6.h Mon Aug 28 09:35:17 2017 (r322965) +++ stable/11/sys/netipsec/ipsec6.h Mon Aug 28 10:02:47 2017 (r322966) @@ -60,7 +60,7 @@ VNET_DECLARE(int, ip6_ipsec_ecn); struct inpcb; struct secpolicy *ipsec6_checkpolicy(const struct mbuf *, - struct inpcb *, int *); + struct inpcb *, int *, int); void ipsec6_setsockaddrs(const struct mbuf *, union sockaddr_union *, union sockaddr_union *); Modified: stable/11/sys/netipsec/ipsec_output.c ============================================================================== --- stable/11/sys/netipsec/ipsec_output.c Mon Aug 28 09:35:17 2017 (r322965) +++ stable/11/sys/netipsec/ipsec_output.c Mon Aug 28 10:02:47 2017 (r322966) @@ -297,7 +297,7 @@ ipsec4_common_output(struct mbuf *m, struct inpcb *inp int error; /* Lookup for the corresponding outbound security policy */ - sp = ipsec4_checkpolicy(m, inp, &error); + sp = ipsec4_checkpolicy(m, inp, &error, !forwarding); if (sp == NULL) { if (error == -EINVAL) { /* Discarded by policy. */ @@ -599,7 +599,7 @@ ipsec6_common_output(struct mbuf *m, struct inpcb *inp int error; /* Lookup for the corresponding outbound security policy */ - sp = ipsec6_checkpolicy(m, inp, &error); + sp = ipsec6_checkpolicy(m, inp, &error, !forwarding); if (sp == NULL) { if (error == -EINVAL) { /* Discarded by policy. */