aboutsummaryrefslogtreecommitdiffstats
path: root/net/appletalk/ddp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-04-27 18:21:23 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-27 18:21:23 -0400
commit1a028e50729b85d0a038fad13daf0ee201a37454 (patch)
treea4ffbf7c5476203e1db51b4bd9d076c69d772697 /net/appletalk/ddp.c
parent50f732ee63b91eb08a29974b36bd63e1150bb642 (diff)
[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.c25
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,
937static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, 937static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
938 int len, unsigned long sum) 938 int len, unsigned long sum)
939{ 939{
940 int end = skb_headlen(skb); 940 int start = skb_headlen(skb);
941 int i, copy; 941 int i, copy;
942 942
943 /* checksum stuff in header space */ 943 /* checksum stuff in header space */
944 if ((copy = end - offset) > 0) { 944 if ( (copy = start - offset) > 0) {
945 if (copy > len) 945 if (copy > len)
946 copy = len; 946 copy = len;
947 sum = atalk_sum_partial(skb->data + offset, copy, sum); 947 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,
953 953
954 /* checksum stuff in frags */ 954 /* checksum stuff in frags */
955 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 955 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
956 BUG_TRAP(len >= 0); 956 int end;
957 957
958 end = offset + skb_shinfo(skb)->frags[i].size; 958 BUG_TRAP(start <= offset + len);
959
960 end = start + skb_shinfo(skb)->frags[i].size;
959 if ((copy = end - offset) > 0) { 961 if ((copy = end - offset) > 0) {
960 u8 *vaddr; 962 u8 *vaddr;
961 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 963 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,
963 if (copy > len) 965 if (copy > len)
964 copy = len; 966 copy = len;
965 vaddr = kmap_skb_frag(frag); 967 vaddr = kmap_skb_frag(frag);
966 sum = atalk_sum_partial(vaddr + frag->page_offset, 968 sum = atalk_sum_partial(vaddr + frag->page_offset +
967 copy, sum); 969 offset - start, copy, sum);
968 kunmap_skb_frag(vaddr); 970 kunmap_skb_frag(vaddr);
969 971
970 if (!(len -= copy)) 972 if (!(len -= copy))
971 return sum; 973 return sum;
972 offset += copy; 974 offset += copy;
973 } 975 }
976 start = end;
974 } 977 }
975 978
976 if (skb_shinfo(skb)->frag_list) { 979 if (skb_shinfo(skb)->frag_list) {
977 struct sk_buff *list = skb_shinfo(skb)->frag_list; 980 struct sk_buff *list = skb_shinfo(skb)->frag_list;
978 981
979 for (; list; list = list->next) { 982 for (; list; list = list->next) {
980 BUG_TRAP(len >= 0); 983 int end;
984
985 BUG_TRAP(start <= offset + len);
981 986
982 end = offset + list->len; 987 end = start + list->len;
983 if ((copy = end - offset) > 0) { 988 if ((copy = end - offset) > 0) {
984 if (copy > len) 989 if (copy > len)
985 copy = len; 990 copy = len;
986 sum = atalk_sum_skb(list, 0, copy, sum); 991 sum = atalk_sum_skb(list, offset - start,
992 copy, sum);
987 if ((len -= copy) == 0) 993 if ((len -= copy) == 0)
988 return sum; 994 return sum;
989 offset += copy; 995 offset += copy;
990 } 996 }
997 start = end;
991 } 998 }
992 } 999 }
993 1000