Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Correct comparisons and calculations using skb->tail and skb-transport_header

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Simon Horman and committed by
David S. Miller
ced14f68 be8b678c

+6 -4
+4 -2
include/net/inet_ecn.h
··· 134 134 { 135 135 switch (skb->protocol) { 136 136 case cpu_to_be16(ETH_P_IP): 137 - if (skb->network_header + sizeof(struct iphdr) <= skb->tail) 137 + if (skb_network_header(skb) + sizeof(struct iphdr) <= 138 + skb_tail_pointer(skb)) 138 139 return IP_ECN_set_ce(ip_hdr(skb)); 139 140 break; 140 141 141 142 case cpu_to_be16(ETH_P_IPV6): 142 - if (skb->network_header + sizeof(struct ipv6hdr) <= skb->tail) 143 + if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= 144 + skb_tail_pointer(skb)) 143 145 return IP6_ECN_set_ce(ipv6_hdr(skb)); 144 146 break; 145 147 }
+2 -2
net/core/dev.c
··· 1724 1724 skb_reset_mac_header(skb2); 1725 1725 1726 1726 if (skb_network_header(skb2) < skb2->data || 1727 - skb2->network_header > skb2->tail) { 1727 + skb_network_header(skb2) > skb_tail_pointer(skb2)) { 1728 1728 net_crit_ratelimited("protocol %04x is buggy, dev %s\n", 1729 1729 ntohs(skb2->protocol), 1730 1730 dev->name); ··· 3892 3892 NAPI_GRO_CB(skb)->frag0 = NULL; 3893 3893 NAPI_GRO_CB(skb)->frag0_len = 0; 3894 3894 3895 - if (skb->mac_header == skb->tail && 3895 + if (skb_mac_header(skb) == skb_tail_pointer(skb) && 3896 3896 pinfo->nr_frags && 3897 3897 !PageHighMem(skb_frag_page(frag0))) { 3898 3898 NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);