net/bonding: fix potential out of bounds read
authorRadu Nicolau <radu.nicolau@intel.com>
Wed, 17 Apr 2019 14:36:47 +0000 (15:36 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 19 Apr 2019 12:51:55 +0000 (14:51 +0200)
Add validation to pointer constructed from the IPv4 header length
in order to prevent malformed packets from generating a potential
out of bounds memory read.

Fixes: 09150784a776 ("net/bonding: burst mode hash calculation")
Cc: stable@dpdk.org
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Acked-by: Chas Williams <chas3@att.com>
drivers/net/bonding/rte_eth_bond_pmd.c

index f30422a..2c4da90 100644 (file)
@@ -841,6 +841,7 @@ burst_xmit_l34_hash(struct rte_mbuf **buf, uint16_t nb_pkts,
 
        for (i = 0; i < nb_pkts; i++) {
                eth_hdr = rte_pktmbuf_mtod(buf[i], struct ether_hdr *);
+               size_t pkt_end = (size_t)eth_hdr + rte_pktmbuf_data_len(buf[i]);
                proto = eth_hdr->ether_type;
                vlan_offset = get_vlan_offset(eth_hdr, &proto);
                l3hash = 0;
@@ -864,13 +865,17 @@ burst_xmit_l34_hash(struct rte_mbuf **buf, uint16_t nb_pkts,
                                        tcp_hdr = (struct tcp_hdr *)
                                                ((char *)ipv4_hdr +
                                                        ip_hdr_offset);
-                                       l4hash = HASH_L4_PORTS(tcp_hdr);
+                                       if ((size_t)tcp_hdr + sizeof(*tcp_hdr)
+                                                       < pkt_end)
+                                               l4hash = HASH_L4_PORTS(tcp_hdr);
                                } else if (ipv4_hdr->next_proto_id ==
                                                                IPPROTO_UDP) {
                                        udp_hdr = (struct udp_hdr *)
                                                ((char *)ipv4_hdr +
                                                        ip_hdr_offset);
-                                       l4hash = HASH_L4_PORTS(udp_hdr);
+                                       if ((size_t)udp_hdr + sizeof(*udp_hdr)
+                                                       < pkt_end)
+                                               l4hash = HASH_L4_PORTS(udp_hdr);
                                }
                        }
                } else if  (rte_cpu_to_be_16(ETHER_TYPE_IPv6) == proto) {