lkml.org 
[lkml]   [2008]   [Feb]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 20/38] INET: Prevent out-of-sync truesize on ip_fragment slow path
2.6.24-stable review patch.  If anyone has any objections, please let us
know.

------------------
Upstream commit: 29ffe1a5c52dae13b6efead97aab9b058f38fce4

When ip_fragment has to hit the slow path the value of skb->truesize
may go out of sync because we would have updated it without changing
the packet length. This violates the constraints on truesize.

This patch postpones the update of skb->truesize to prevent this.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
net/ipv4/ip_output.c | 4 +++-
net/ipv6/ip6_output.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)

--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -462,6 +462,7 @@ int ip_fragment(struct sk_buff *skb, int
if (skb_shinfo(skb)->frag_list) {
struct sk_buff *frag;
int first_len = skb_pagelen(skb);
+ int truesizes = 0;

if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
@@ -485,7 +486,7 @@ int ip_fragment(struct sk_buff *skb, int
sock_hold(skb->sk);
frag->sk = skb->sk;
frag->destructor = sock_wfree;
- skb->truesize -= frag->truesize;
+ truesizes += frag->truesize;
}
}

@@ -496,6 +497,7 @@ int ip_fragment(struct sk_buff *skb, int
frag = skb_shinfo(skb)->frag_list;
skb_shinfo(skb)->frag_list = NULL;
skb->data_len = first_len - skb_headlen(skb);
+ skb->truesize -= truesizes;
skb->len = first_len;
iph->tot_len = htons(first_len);
iph->frag_off = htons(IP_MF);
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -609,6 +609,7 @@ static int ip6_fragment(struct sk_buff *

if (skb_shinfo(skb)->frag_list) {
int first_len = skb_pagelen(skb);
+ int truesizes = 0;

if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
@@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *
sock_hold(skb->sk);
frag->sk = skb->sk;
frag->destructor = sock_wfree;
- skb->truesize -= frag->truesize;
+ truesizes += frag->truesize;
}
}

@@ -662,6 +663,7 @@ static int ip6_fragment(struct sk_buff *

first_len = skb_pagelen(skb);
skb->data_len = first_len - skb_headlen(skb);
+ skb->truesize -= truesizes;
skb->len = first_len;
ipv6_hdr(skb)->payload_len = htons(first_len -
sizeof(struct ipv6hdr));
--


\
 
 \ /
  Last update: 2008-02-23 01:45    [W:1.195 / U:0.112 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site