From 22bbefb2c9e93a7695900fab3ade9863a826744f Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Mon, 21 Aug 2017 13:52:21 +0000 Subject: 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 after: 1 week --- sys/netipsec/ipsec.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'sys/netipsec/ipsec.c') diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index e120f654aac0..15be36014a01 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -563,7 +563,8 @@ ipsec4_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx) } 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; @@ -573,7 +574,7 @@ ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int 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 +587,13 @@ ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) * 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 +625,7 @@ ipsec4_in_reject(const struct mbuf *m, struct inpcb *inp) 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 +733,8 @@ ipsec6_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx) } 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; @@ -741,7 +744,7 @@ ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int 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 +757,13 @@ ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) * 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 +795,7 @@ ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp) 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) -- cgit v1.2.3