[patch 20/38] INET: Prevent out-of-sync truesize on ip_fragment slow path

2008-02-22 Thread Greg KH
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 <[EMAIL PROTECTED]>
Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>

---
 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));

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[patch 20/38] INET: Prevent out-of-sync truesize on ip_fragment slow path

2008-02-22 Thread Greg KH
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 [EMAIL PROTECTED]
Signed-off-by: David S. Miller [EMAIL PROTECTED]
Signed-off-by: Greg Kroah-Hartman [EMAIL PROTECTED]

---
 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));

-- 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/