summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2003-04-22 02:52:29 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2003-04-22 02:52:29 +0000
commitc7bcbfb3053ac8d50492c63e128daa1655202712 (patch)
treee4b195f10bf5cdb507298b42005c04a69a401014 /sys/netinet
parent0b65acf8b3451a16f1aeed826f1acd316e961c48 (diff)
correct (false) assumption made about m->m_len. dhartmei ok.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_gre.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index f6fe4d60943..38cedbc0e62 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.c,v 1.19 2002/08/16 09:32:39 itojun Exp $ */
+/* $OpenBSD: ip_gre.c,v 1.20 2003/04/22 02:52:28 itojun Exp $ */
/* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -103,7 +103,7 @@ gre_input2(m , hlen, proto)
int hlen;
u_char proto;
{
- register struct greip *gip = mtod(m, struct greip *);
+ register struct greip *gip;
register int s;
register struct ifqueue *ifq;
struct gre_softc *sc;
@@ -115,6 +115,13 @@ gre_input2(m , hlen, proto)
return (0);
}
+ if (m->m_len < sizeof(*gip)) {
+ m = m_pullup(m, sizeof(*gip));
+ if (m == NULL)
+ return (ENOBUFS);
+ }
+ gip = mtod(m, struct greip *);
+
m->m_pkthdr.rcvif = &sc->sc_if;
sc->sc_if.if_ipackets++;
@@ -190,9 +197,11 @@ gre_input2(m , hlen, proto)
return (0);
}
- m->m_data += hlen;
- m->m_len -= hlen;
- m->m_pkthdr.len -= hlen;
+ if (hlen > m->m_pkthdr.len) {
+ m_freem(m);
+ return (EINVAL);
+ }
+ m_adj(m, hlen);
#if NBPFILTER > 0
if (sc->sc_if.if_bpf) {
@@ -233,7 +242,7 @@ gre_input2(m , hlen, proto)
void
gre_input(struct mbuf *m, ...)
{
- register int hlen,ret;
+ register int hlen, ret;
va_list ap;
va_start(ap, m);
@@ -267,16 +276,16 @@ gre_input(struct mbuf *m, ...)
void
gre_mobile_input(struct mbuf *m, ...)
{
- register struct ip *ip = mtod(m, struct ip *);
- register struct mobip_h *mip = mtod(m, struct mobip_h *);
+ register struct ip *ip;
+ register struct mobip_h *mip;
register struct ifqueue *ifq;
struct gre_softc *sc;
- register int hlen,s;
+ register int hlen, s;
va_list ap;
u_char osrc = 0;
int msiz;
- va_start(ap,m);
+ va_start(ap, m);
hlen = va_arg(ap, int);
va_end(ap);
@@ -291,22 +300,38 @@ gre_mobile_input(struct mbuf *m, ...)
return;
}
+ if (m->m_len < sizeof(*mip)) {
+ m = m_pullup(m, sizeof(*mip));
+ if (m == NULL)
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ mip = mtod(m, struct mobip_h *);
+
m->m_pkthdr.rcvif = &sc->sc_if;
sc->sc_if.if_ipackets++;
sc->sc_if.if_ibytes += m->m_pkthdr.len;
- if(ntohs(mip->mh.proto) & MOB_H_SBIT) {
+ if (ntohs(mip->mh.proto) & MOB_H_SBIT) {
osrc = 1;
msiz = MOB_H_SIZ_L;
mip->mi.ip_src.s_addr = mip->mh.osrc;
- } else {
+ } else
msiz = MOB_H_SIZ_S;
+
+ if (m->m_len < (ip->ip_hl << 2) + msiz) {
+ m = m_pullup(m, (ip->ip_hl << 2) + msiz);
+ if (m == NULL)
+ return;
+ ip = mtod(m, struct ip *);
+ mip = mtod(m, struct mobip_h *);
}
+
mip->mi.ip_dst.s_addr = mip->mh.odst;
mip->mi.ip_p = (ntohs(mip->mh.proto) >> 8);
- if (gre_in_cksum((u_short *) &mip->mh,msiz) != 0) {
+ if (gre_in_cksum((u_short *) &mip->mh, msiz) != 0) {
m_freem(m);
return;
}