summaryrefslogtreecommitdiff
path: root/sys/netinet/ipsec_input.c
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2003-07-08 11:01:21 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2003-07-08 11:01:21 +0000
commit04dc983bee686e36ce48f0266b054200649de5de (patch)
treedf7eb01bc40fbfff06bcb9a3e50ffe05e74dd299 /sys/netinet/ipsec_input.c
parent3fdb79dfdd32998f85902cb82552ef9060009fbe (diff)
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; ok angelos@
Diffstat (limited to 'sys/netinet/ipsec_input.c')
-rw-r--r--sys/netinet/ipsec_input.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index a279ec95167..4a8e58fc620 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.65 2003/07/04 16:40:55 markus Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.66 2003/07/08 11:01:20 markus Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -314,8 +314,15 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
/* IP-in-IP encapsulation */
if (prot == IPPROTO_IPIP) {
+ if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
+ m_freem(m);
+ IPSEC_ISTAT(espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ return EINVAL;
+ }
/* ipn will now contain the inner IPv4 header */
- m_copydata(m, ip->ip_hl << 2, sizeof(struct ip),
+ m_copydata(m, skip, sizeof(struct ip),
(caddr_t) &ipn);
/*
@@ -349,8 +356,15 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
#if INET6
/* IPv6-in-IP encapsulation. */
if (prot == IPPROTO_IPV6) {
+ if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
+ m_freem(m);
+ IPSEC_ISTAT(espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ return EINVAL;
+ }
/* ip6n will now contain the inner IPv6 header. */
- m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr),
+ m_copydata(m, skip, sizeof(struct ip6_hdr),
(caddr_t) &ip6n);
/*
@@ -409,6 +423,13 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
#ifdef INET
/* IP-in-IP encapsulation */
if (prot == IPPROTO_IPIP) {
+ if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
+ m_freem(m);
+ IPSEC_ISTAT(espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ return EINVAL;
+ }
/* ipn will now contain the inner IPv4 header */
m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
@@ -443,6 +464,13 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
/* IPv6-in-IP encapsulation */
if (prot == IPPROTO_IPV6) {
+ if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
+ m_freem(m);
+ IPSEC_ISTAT(espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ return EINVAL;
+ }
/* ip6n will now contain the inner IPv6 header. */
m_copydata(m, skip, sizeof(struct ip6_hdr),
(caddr_t) &ip6n);