DF-0742 / fix.diff
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -140,6 +140,18 @@ return (0); } + /* + * Ensure the GRE header overlay (struct greip = struct ip + + * struct gre_h) is contiguous in the head mbuf before we + * dereference gi_flags / gi_ptype at byte offset 20+. ip_input + * only guarantees m_len >= ip_hl*4; on chained mbufs (e.g. after + * ip_reass m_cat) the GRE header may live in m_next, and the + * overlay derefs would read stale mbuf-cluster residue (DF-0742). + */ + if ((m = m_pullup(m, sizeof(struct greip))) == NULL) + return (1); + gip = mtod(m, struct greip *); + IFNET_STAT_INC(&sc->sc_if, ipackets, 1); IFNET_STAT_INC(&sc->sc_if, ibytes, m->m_pkthdr.len); @@ -217,6 +229,23 @@ return(IPPROTO_DONE); } + /* + * Ensure the mobile header overlay (struct mobip_h = struct ip + + * struct mobile_h) is contiguous in the head mbuf before we + * dereference mh.proto / mh.osrc / mh.odst / gre_in_cksum at byte + * offset 20+. ip_input only guarantees m_len >= ip_hl*4; on + * chained mbufs (e.g. after ip_reass m_cat) the mobile header may + * live in m_next, and the overlay derefs would read stale + * mbuf-cluster residue (DF-0742). + */ + if ((m = m_pullup(m, sizeof(struct mobip_h))) == NULL) { + *mp = NULL; + return (IPPROTO_DONE); + } + *mp = m; + ip = mtod(m, struct ip *); + mip = mtod(m, struct mobip_h *); + IFNET_STAT_INC(&sc->sc_if, ipackets, 1); IFNET_STAT_INC(&sc->sc_if, ibytes, m->m_pkthdr.len); |