diff options
author | sam <sam@FreeBSD.org> | 2003-08-13 22:36:24 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2003-08-13 22:36:24 +0000 |
commit | 7945dbb7bd8e4ee97efa0e69f1beb58618e87ab9 (patch) | |
tree | ad3dccfc964194f0b4c01d94d0af9b76c55ee24f /sys/netipsec | |
parent | af81e4b88b676946e3442bf7d4f9af2e40838249 (diff) | |
download | FreeBSD-src-7945dbb7bd8e4ee97efa0e69f1beb58618e87ab9.zip FreeBSD-src-7945dbb7bd8e4ee97efa0e69f1beb58618e87ab9.tar.gz |
make sure the packets contains a complete inner header
for ip{4,6}-in-ip{4,6} encapsulation; fixes panic
for truncated ip-in-ip over ipsec
Submitted by: Markus Friedl <markus@openbsd.org>
Obtained from: OpenBSD (rev 1.66 ipsec_input.c)
Diffstat (limited to 'sys/netipsec')
-rw-r--r-- | sys/netipsec/ipsec_input.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index fb64a05..17e5218 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -323,6 +323,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, if (prot == IPPROTO_IPIP) { struct ip ipn; + if (m->m_pkthdr.len - skip < sizeof(struct ip)) { + IPSEC_ISTAT(sproto, espstat.esps_hdrops, + ahstat.ahs_hdrops, + ipcompstat.ipcomps_hdrops); + error = EINVAL; + goto bad; + } /* ipn will now contain the inner IPv4 header */ m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), (caddr_t) &ipn); @@ -362,6 +369,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, if (prot == IPPROTO_IPV6) { struct ip6_hdr ip6n; + if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { + IPSEC_ISTAT(sproto, espstat.esps_hdrops, + ahstat.ahs_hdrops, + ipcompstat.ipcomps_hdrops); + error = EINVAL; + goto bad; + } /* ip6n will now contain the inner IPv6 header. */ m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), (caddr_t) &ip6n); @@ -633,6 +647,13 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto if (prot == IPPROTO_IPIP) { struct ip ipn; + if (m->m_pkthdr.len - skip < sizeof(struct ip)) { + IPSEC_ISTAT(sproto, espstat.esps_hdrops, + ahstat.ahs_hdrops, + ipcompstat.ipcomps_hdrops); + error = EINVAL; + goto bad; + } /* ipn will now contain the inner IPv4 header */ m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn); @@ -668,6 +689,13 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto if (prot == IPPROTO_IPV6) { struct ip6_hdr ip6n; + if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { + IPSEC_ISTAT(sproto, espstat.esps_hdrops, + ahstat.ahs_hdrops, + ipcompstat.ipcomps_hdrops); + error = EINVAL; + goto bad; + } /* ip6n will now contain the inner IPv6 header. */ m_copydata(m, skip, sizeof(struct ip6_hdr), (caddr_t) &ip6n); |