diff options
author | Alexander Drozdov <al.drozdov@gmail.com> | 2015-03-05 10:29:39 +0300 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2015-05-09 23:16:37 +0100 |
commit | cab55ceea3dd6f5c3ae1a788ecbf08067c478f54 (patch) | |
tree | 904a2e0c6fdafd77e92224494d562bc9185c1d3d /net | |
parent | 24aa85b0d9ef3f2cd3d99be59bbf58fba269ba08 (diff) | |
download | lwn-cab55ceea3dd6f5c3ae1a788ecbf08067c478f54.tar.gz lwn-cab55ceea3dd6f5c3ae1a788ecbf08067c478f54.zip |
ipv4: ip_check_defrag should not assume that skb_network_offset is zero
[ Upstream commit 3e32e733d1bbb3f227259dc782ef01d5706bdae0 ]
ip_check_defrag() may be used by af_packet to defragment outgoing packets.
skb_network_offset() of af_packet's outgoing packets is not zero.
Signed-off-by: Alexander Drozdov <al.drozdov@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_fragment.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index fbe920f5cc00..16e25a4c14a0 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -692,27 +692,30 @@ EXPORT_SYMBOL(ip_defrag); struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) { struct iphdr iph; + int netoff; u32 len; if (skb->protocol != htons(ETH_P_IP)) return skb; - if (skb_copy_bits(skb, 0, &iph, sizeof(iph)) < 0) + netoff = skb_network_offset(skb); + + if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0) return skb; if (iph.ihl < 5 || iph.version != 4) return skb; len = ntohs(iph.tot_len); - if (skb->len < len || len < (iph.ihl * 4)) + if (skb->len < netoff + len || len < (iph.ihl * 4)) return skb; if (ip_is_fragment(&iph)) { skb = skb_share_check(skb, GFP_ATOMIC); if (skb) { - if (!pskb_may_pull(skb, iph.ihl*4)) + if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) return skb; - if (pskb_trim_rcsum(skb, len)) + if (pskb_trim_rcsum(skb, netoff + len)) return skb; memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); if (ip_defrag(skb, user)) |