Index: if_ix.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_ix.c,v retrieving revision 1.113 diff -u -p -r1.113 if_ix.c --- if_ix.c 22 Dec 2014 02:28:52 -0000 1.113 +++ if_ix.c 28 Dec 2014 11:53:00 -0000 @@ -2035,14 +2049,13 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct ix_softc *sc = txr->sc; struct ixgbe_adv_tx_context_desc *TXD; struct ixgbe_tx_buf *tx_buffer; + struct ether_header eh; #if NVLAN > 0 - struct ether_vlan_header *eh; -#else - struct ether_header *eh; + struct ether_vlan_header evh; #endif - struct ip *ip; + struct ip ip; #ifdef notyet - struct ip6_hdr *ip6; + struct ip6_hdr ip6; #endif uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0; int ehdrlen, ip_hlen = 0; @@ -2089,19 +2102,21 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, * Jump over vlan headers if already present, * helpful for QinQ too. */ + if (mp->m_pkthdr.len < sizeof(eh)) + return (1); + + m_copydata(mp, 0, sizeof(eh), (caddr_t)&eh); + etype = ntohs(eh.ether_type); + ehdrlen = ETHER_HDR_LEN; #if NVLAN > 0 - eh = mtod(mp, struct ether_vlan_header *); - if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { - etype = ntohs(eh->evl_proto); - ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; - } else { - etype = ntohs(eh->evl_encap_proto); - ehdrlen = ETHER_HDR_LEN; + if (etype == htons(ETHERTYPE_VLAN)) { + if (mp->m_pkthdr.len < sizeof(evh)) + return (1); + + m_copydata(mp, 0, sizeof(evh), (caddr_t)&evh); + etype = ntohs(evh.evl_proto); + ehdrlen = sizeof(evh); } -#else - eh = mtod(mp, struct ether_header *); - etype = ntohs(eh->ether_type); - ehdrlen = ETHER_HDR_LEN; #endif /* Set the ether header length */ @@ -2109,17 +2124,23 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, switch (etype) { case ETHERTYPE_IP: - ip = (struct ip *)(mp->m_data + ehdrlen); - ip_hlen = ip->ip_hl << 2; - ipproto = ip->ip_p; + if (mp->m_pkthdr.len < ehdrlen + sizeof(ip)) + return (1); + + m_copydata(mp, ehdrlen, sizeof(ip), (caddr_t)&ip); + ip_hlen = ip.ip_hl << 2; + ipproto = ip.ip_p; type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; break; #ifdef notyet case ETHERTYPE_IPV6: - ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); - ip_hlen = sizeof(struct ip6_hdr); + if (mp->m_pkthdr.len < ehdrlen + sizeof(ip6)) + return (1); + + m_copydata(mp, ehdrlen, sizeof(ip6), (caddr_t)&ip6); + ip_hlen = sizeof(ip6); /* XXX-BZ this will go badly in case of ext hdrs. */ - ipproto = ip6->ip6_nxt; + ipproto = ip6.ip6_nxt; type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; break; #endif