aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorShyam Iyer <shyam_iyer@dell.com>2009-01-29 19:12:42 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-29 19:12:42 -0500
commit71b3346d182355f19509fadb8fe45114a35cc499 (patch)
tree4f22b15445a0b722dc124ca66f23fddc689f0bf9 /net
parent95e3b24cfb4ec0479d2c42f7a1780d68063a542a (diff)
net: Fix OOPS in skb_seq_read().
It oopsd for me in skb_seq_read. addr2line said it was linux-2.6/net/core/skbuff.c:2228, which is this line: while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) { I added some printks in there and it looks like we hit this: } else if (st->root_skb == st->cur_skb && skb_shinfo(st->root_skb)->frag_list) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; } Actually I did some testing and added a few printks and found that the st->cur_skb->data was 0 and hence the ptr used by iscsi_tcp was null. This caused the kernel panic. if (abs_offset < block_limit) { - *data = st->cur_skb->data + abs_offset; + *data = st->cur_skb->data + (abs_offset - st->stepped_offset); I enabled the debug_tcp and with a few printks found that the code did not go to the next_skb label and could find that the sequence being followed was this - It hit this if condition - if (st->cur_skb->next) { st->cur_skb = st->cur_skb->next; st->frag_idx = 0; goto next_skb; And so, now the st pointer is shifted to the next skb whereas actually it should have hit the second else if first since the data is in the frag_list. else if (st->root_skb == st->cur_skb && skb_shinfo(st->root_skb)->frag_list) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; goto next_skb; } Reversing the two conditions the attached patch fixes the issue for me on top of Herbert's patches. Signed-off-by: Shyam Iyer <shyam_iyer@dell.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/skbuff.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f23fd43539ed..da74b844f4ea 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2250,13 +2250,13 @@ next_skb:
2250 st->frag_data = NULL; 2250 st->frag_data = NULL;
2251 } 2251 }
2252 2252
2253 if (st->cur_skb->next) { 2253 if (st->root_skb == st->cur_skb &&
2254 st->cur_skb = st->cur_skb->next; 2254 skb_shinfo(st->root_skb)->frag_list) {
2255 st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
2255 st->frag_idx = 0; 2256 st->frag_idx = 0;
2256 goto next_skb; 2257 goto next_skb;
2257 } else if (st->root_skb == st->cur_skb && 2258 } else if (st->cur_skb->next) {
2258 skb_shinfo(st->root_skb)->frag_list) { 2259 st->cur_skb = st->cur_skb->next;
2259 st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
2260 st->frag_idx = 0; 2260 st->frag_idx = 0;
2261 goto next_skb; 2261 goto next_skb;
2262 } 2262 }