aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_algo.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/xfrm/xfrm_algo.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/xfrm/xfrm_algo.c')
-rw-r--r--net/xfrm/xfrm_algo.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index be529c4241a6..6249a9405bb8 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -532,8 +532,8 @@ EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
532int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, 532int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
533 int offset, int len, icv_update_fn_t icv_update) 533 int offset, int len, icv_update_fn_t icv_update)
534{ 534{
535 int end = skb_headlen(skb); 535 int start = skb_headlen(skb);
536 int i, copy = end - offset; 536 int i, copy = start - offset;
537 int err; 537 int err;
538 struct scatterlist sg; 538 struct scatterlist sg;
539 539
@@ -556,9 +556,11 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
556 } 556 }
557 557
558 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 558 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
559 BUG_TRAP(len >= 0); 559 int end;
560 560
561 end = offset + skb_shinfo(skb)->frags[i].size; 561 BUG_TRAP(start <= offset + len);
562
563 end = start + skb_shinfo(skb)->frags[i].size;
562 if ((copy = end - offset) > 0) { 564 if ((copy = end - offset) > 0) {
563 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 565 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
564 566
@@ -566,7 +568,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
566 copy = len; 568 copy = len;
567 569
568 sg.page = frag->page; 570 sg.page = frag->page;
569 sg.offset = frag->page_offset; 571 sg.offset = frag->page_offset + offset-start;
570 sg.length = copy; 572 sg.length = copy;
571 573
572 err = icv_update(desc, &sg, copy); 574 err = icv_update(desc, &sg, copy);
@@ -577,19 +579,22 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
577 return 0; 579 return 0;
578 offset += copy; 580 offset += copy;
579 } 581 }
582 start = end;
580 } 583 }
581 584
582 if (skb_shinfo(skb)->frag_list) { 585 if (skb_shinfo(skb)->frag_list) {
583 struct sk_buff *list = skb_shinfo(skb)->frag_list; 586 struct sk_buff *list = skb_shinfo(skb)->frag_list;
584 587
585 for (; list; list = list->next) { 588 for (; list; list = list->next) {
586 BUG_TRAP(len >= 0); 589 int end;
590
591 BUG_TRAP(start <= offset + len);
587 592
588 end = offset + list->len; 593 end = start + list->len;
589 if ((copy = end - offset) > 0) { 594 if ((copy = end - offset) > 0) {
590 if (copy > len) 595 if (copy > len)
591 copy = len; 596 copy = len;
592 err = skb_icv_walk(list, desc, 0, 597 err = skb_icv_walk(list, desc, offset-start,
593 copy, icv_update); 598 copy, icv_update);
594 if (unlikely(err)) 599 if (unlikely(err))
595 return err; 600 return err;
@@ -597,6 +602,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
597 return 0; 602 return 0;
598 offset += copy; 603 offset += copy;
599 } 604 }
605 start = end;
600 } 606 }
601 } 607 }
602 BUG_ON(len); 608 BUG_ON(len);