summaryrefslogtreecommitdiff
path: root/net/xfrm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-04-28 02:21:23 +0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-28 02:21:23 +0400
commit1a028e50729b85d0a038fad13daf0ee201a37454 (patch)
treea4ffbf7c5476203e1db51b4bd9d076c69d772697 /net/xfrm
parent50f732ee63b91eb08a29974b36bd63e1150bb642 (diff)
downloadlinux-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/xfrm')
-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);
int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
int offset, int len, icv_update_fn_t icv_update)
{
- int end = skb_headlen(skb);
- int i, copy = end - offset;
+ int start = skb_headlen(skb);
+ int i, copy = start - offset;
int err;
struct scatterlist sg;
@@ -556,9 +556,11 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
}
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) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -566,7 +568,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
copy = len;
sg.page = frag->page;
- sg.offset = frag->page_offset;
+ sg.offset = frag->page_offset + offset-start;
sg.length = copy;
err = icv_update(desc, &sg, copy);
@@ -577,19 +579,22 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
return 0;
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;
- err = skb_icv_walk(list, desc, 0,
+ err = skb_icv_walk(list, desc, offset-start,
copy, icv_update);
if (unlikely(err))
return err;
@@ -597,6 +602,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
return 0;
offset += copy;
}
+ start = end;
}
}
BUG_ON(len);