diff mbox

[3.13.y-ckt,stable] Patch "ipv4: ip_check_defrag should not assume that skb_network_offset is zero" has been added to staging queue

Message ID 1428357504-16330-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa April 6, 2015, 9:58 p.m. UTC
This is a note to let you know that I have just added a patch titled

    ipv4: ip_check_defrag should not assume that skb_network_offset is zero

to the linux-3.13.y-queue branch of the 3.13.y-ckt extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue

This patch is scheduled to be released in version 3.13.11-ckt19.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.13.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

From 65135a409e0b54fc89b4c6b32467058e6c45168a Mon Sep 17 00:00:00 2001
From: Alexander Drozdov <al.drozdov@gmail.com>
Date: Thu, 5 Mar 2015 10:29:39 +0300
Subject: 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: Kamal Mostafa <kamal@canonical.com>
---
 net/ipv4/ip_fragment.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

--
1.9.1
diff mbox

Patch

diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index d422e46..a679298 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -679,27 +679,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))