Subject: [PATCH RFC] ixgbe: ixgbe_atr() must check if network header is available in headlen

From: Sowmini Varadhan <[email-masked]>
Date: Sat, 15 Oct 2016 17:31:04 -0400

For some Tx paths (e.g., tpacket_snd()), ixgbe_atr may be
passed down an sk_buff that has the network and transport
header in the paged data, so it needs to make sure these
headers are available in the headlen bytes to calculate the
l4_proto.

This patch bails out if the headlen is "too short", and does
not attempt to call skb_header_pointer() to get the needed
bytes: the assumption is that the caller should set things
up properly if the l4_proto based tx steering is desired.

Signed-off-by: Sowmini Varadhan <[email-masked]>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a244d9a..0868de1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7632,6 +7632,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
 	struct sk_buff *skb;
 	__be16 vlan_id;
 	int l4_proto;
+	int min_hdr_size = 0;
 
 	/* if ring doesn't have a interrupt vector, cannot perform ATR */
 	if (!q_vector)
@@ -7650,6 +7651,14 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
 
 	/* snag network header to get L4 type and address */
 	skb = first->skb;
+	if (first->protocol == htons(ETH_P_IP))
+		min_hdr_size = sizeof(struct iphdr) +
+			       sizeof(struct tcphdr);
+	else if (first->protocol == htons(ETH_P_IPV6))
+		min_hdr_size = sizeof(struct ipv6hdr) +
+			       sizeof(struct tcphdr);
+	if (min_hdr_size && skb_headlen(skb) < ETH_HLEN + min_hdr_size)
+		return;
 	hdr.network = skb_network_header(skb);
 	if (skb->encapsulation &&
 	    first->protocol == htons(ETH_P_IP) &&
-- 
1.7.1