diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-09 13:04:41 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:37 +0200 |
commit | e4a8065910cd6b2e7e0448cc6431ca2906322389 (patch) | |
tree | 73492991cfa40f994c20d761d476e6bc16304536 /freebsd/sys/netipsec | |
parent | Update to FreeBSD head 2017-08-01 (diff) | |
download | rtems-libbsd-e4a8065910cd6b2e7e0448cc6431ca2906322389.tar.bz2 |
Update to FreeBSD head 2017-10-01
Git mirror commit b2f0376b45428f13151d229c5ae9d4d8f74acbd1.
Update #3472.
Diffstat (limited to 'freebsd/sys/netipsec')
-rw-r--r-- | freebsd/sys/netipsec/ipsec.c | 26 | ||||
-rw-r--r-- | freebsd/sys/netipsec/ipsec.h | 2 | ||||
-rw-r--r-- | freebsd/sys/netipsec/ipsec6.h | 2 | ||||
-rw-r--r-- | freebsd/sys/netipsec/ipsec_output.c | 4 | ||||
-rw-r--r-- | freebsd/sys/netipsec/key.c | 26 | ||||
-rw-r--r-- | freebsd/sys/netipsec/udpencap.c | 7 | ||||
-rw-r--r-- | freebsd/sys/netipsec/xform_ah.c | 4 |
7 files changed, 43 insertions, 28 deletions
diff --git a/freebsd/sys/netipsec/ipsec.c b/freebsd/sys/netipsec/ipsec.c index 4b44a8ce..79c9519c 100644 --- a/freebsd/sys/netipsec/ipsec.c +++ b/freebsd/sys/netipsec/ipsec.c @@ -565,7 +565,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; @@ -574,8 +575,7 @@ ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) 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); } @@ -588,12 +588,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) { @@ -625,7 +626,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) @@ -733,7 +734,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; @@ -742,8 +744,7 @@ ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) 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); } @@ -756,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) { @@ -793,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) diff --git a/freebsd/sys/netipsec/ipsec.h b/freebsd/sys/netipsec/ipsec.h index a4c3f3d2..a61730ef 100644 --- a/freebsd/sys/netipsec/ipsec.h +++ b/freebsd/sys/netipsec/ipsec.h @@ -320,7 +320,7 @@ int ipsec_if_input(struct mbuf *, struct secasvar *, uint32_t); 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); diff --git a/freebsd/sys/netipsec/ipsec6.h b/freebsd/sys/netipsec/ipsec6.h index a5fae4d1..33aa30f3 100644 --- a/freebsd/sys/netipsec/ipsec6.h +++ b/freebsd/sys/netipsec/ipsec6.h @@ -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 *); diff --git a/freebsd/sys/netipsec/ipsec_output.c b/freebsd/sys/netipsec/ipsec_output.c index 07e39a8a..ac9529d5 100644 --- a/freebsd/sys/netipsec/ipsec_output.c +++ b/freebsd/sys/netipsec/ipsec_output.c @@ -299,7 +299,7 @@ ipsec4_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) 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. */ @@ -601,7 +601,7 @@ ipsec6_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) 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. */ diff --git a/freebsd/sys/netipsec/key.c b/freebsd/sys/netipsec/key.c index 0dfab7bd..ef5d8419 100644 --- a/freebsd/sys/netipsec/key.c +++ b/freebsd/sys/netipsec/key.c @@ -1405,7 +1405,8 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int *error) while (tlen > 0) { /* length check */ - if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { + if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr) || + xisr->sadb_x_ipsecrequest_len > tlen) { ipseclog((LOG_DEBUG, "%s: invalid ipsecrequest " "length.\n", __func__)); key_freesp(&newsp); @@ -1519,10 +1520,12 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int *error) if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { struct sockaddr *paddr; + len = tlen - sizeof(*xisr); paddr = (struct sockaddr *)(xisr + 1); /* validity check */ - if (paddr->sa_len - > sizeof(isr->saidx.src)) { + if (len < sizeof(struct sockaddr) || + len < 2 * paddr->sa_len || + paddr->sa_len > sizeof(isr->saidx.src)) { ipseclog((LOG_DEBUG, "%s: invalid " "request address length.\n", __func__)); @@ -1530,13 +1533,26 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int *error) *error = EINVAL; return NULL; } + /* + * Request length should be enough to keep + * source and destination addresses. + */ + if (xisr->sadb_x_ipsecrequest_len < + sizeof(*xisr) + 2 * paddr->sa_len) { + ipseclog((LOG_DEBUG, "%s: invalid " + "ipsecrequest length.\n", + __func__)); + key_freesp(&newsp); + *error = EINVAL; + return (NULL); + } bcopy(paddr, &isr->saidx.src, paddr->sa_len); paddr = (struct sockaddr *)((caddr_t)paddr + paddr->sa_len); /* validity check */ - if (paddr->sa_len - > sizeof(isr->saidx.dst)) { + if (paddr->sa_len != + isr->saidx.src.sa.sa_len) { ipseclog((LOG_DEBUG, "%s: invalid " "request address length.\n", __func__)); diff --git a/freebsd/sys/netipsec/udpencap.c b/freebsd/sys/netipsec/udpencap.c index 265461cd..3eb106b2 100644 --- a/freebsd/sys/netipsec/udpencap.c +++ b/freebsd/sys/netipsec/udpencap.c @@ -122,7 +122,7 @@ udp_ipsec_input(struct mbuf *m, int off, int af) struct udphdr *udp; struct ip *ip; uint32_t spi; - int error, hlen; + int hlen; /* * Just return if packet doesn't have enough data. @@ -207,10 +207,7 @@ udp_ipsec_input(struct mbuf *m, int off, int af) * will do this anyway, so don't touch them here. */ ESPSTAT_INC(esps_input); - error = (*sav->tdb_xform->xf_input)(m, sav, hlen, off); - if (error != 0) - key_freesav(&sav); - + (*sav->tdb_xform->xf_input)(m, sav, hlen, off); return (EINPROGRESS); /* Consumed by IPsec. */ } diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c index 9c2620f4..6e9baa1f 100644 --- a/freebsd/sys/netipsec/xform_ah.c +++ b/freebsd/sys/netipsec/xform_ah.c @@ -195,9 +195,9 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria) return EINVAL; } keylen = _KEYLEN(sav->key_auth); - if (keylen != thash->keysize && thash->keysize != 0) { + if (keylen > thash->keysize && thash->keysize != 0) { DPRINTF(("%s: invalid keylength %d, algorithm %s requires " - "keysize %d\n", __func__, + "keysize less than %d\n", __func__, keylen, thash->name, thash->keysize)); return EINVAL; } |