diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-04-28 02:21:23 +0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-28 02:21:23 +0400 |
commit | 1a028e50729b85d0a038fad13daf0ee201a37454 (patch) | |
tree | a4ffbf7c5476203e1db51b4bd9d076c69d772697 /net/appletalk/ddp.c | |
parent | 50f732ee63b91eb08a29974b36bd63e1150bb642 (diff) | |
download | linux-1a028e50729b85d0a038fad13daf0ee201a37454.tar.xz |
[NET]: Revert sk_buff walker cleanups.
This reverts eefa3906283a2b60a6d02a2cda593a7d7d7946c5
The simplification made in that change works with the assumption that
the 'offset' parameter to these functions is always positive or zero,
which is not true. It can be and often is negative in order to access
SKB header values in front of skb->data.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/appletalk/ddp.c')
-rw-r--r-- | net/appletalk/ddp.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 16eda21fb38c..f6a92a0b7aa6 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -937,11 +937,11 @@ static unsigned long atalk_sum_partial(const unsigned char *data, static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, int len, unsigned long sum) { - int end = skb_headlen(skb); + int start = skb_headlen(skb); int i, copy; /* checksum stuff in header space */ - if ((copy = end - offset) > 0) { + if ( (copy = start - offset) > 0) { if (copy > len) copy = len; sum = atalk_sum_partial(skb->data + offset, copy, sum); @@ -953,9 +953,11 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, /* checksum stuff in frags */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - BUG_TRAP(len >= 0); + int end; - end = offset + skb_shinfo(skb)->frags[i].size; + BUG_TRAP(start <= offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { u8 *vaddr; skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -963,31 +965,36 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, if (copy > len) copy = len; vaddr = kmap_skb_frag(frag); - sum = atalk_sum_partial(vaddr + frag->page_offset, - copy, sum); + sum = atalk_sum_partial(vaddr + frag->page_offset + + offset - start, copy, sum); kunmap_skb_frag(vaddr); if (!(len -= copy)) return sum; offset += copy; } + start = end; } if (skb_shinfo(skb)->frag_list) { struct sk_buff *list = skb_shinfo(skb)->frag_list; for (; list; list = list->next) { - BUG_TRAP(len >= 0); + int end; + + BUG_TRAP(start <= offset + len); - end = offset + list->len; + end = start + list->len; if ((copy = end - offset) > 0) { if (copy > len) copy = len; - sum = atalk_sum_skb(list, 0, copy, sum); + sum = atalk_sum_skb(list, offset - start, + copy, sum); if ((len -= copy) == 0) return sum; offset += copy; } + start = end; } } |