Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Aug 2017 10:02:47 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
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
Message-ID:  <201708281002.v7SA2lXu071028@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <dewayne.geraghty at heuristicsystems.com.au>
  
  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. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708281002.v7SA2lXu071028>