/[linux-patches]/genpatches-2.6/trunk/2.6.14/1439_15.5_reallow-recursive-skb-frag-lists.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.14/1439_15.5_reallow-recursive-skb-frag-lists.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (show annotations) (download) (as text)
Tue Mar 14 13:34:17 2006 UTC (14 years, 8 months ago) by johnm
File MIME type: text/x-diff
File size: 3222 byte(s)
2.6.14-11, rebase against local tree
1 From: David S. Miller <davem@davemloft.net>
2 Date: Tue, 14 Feb 2006 00:46:25 +0000 (-0800)
3 Subject: [PATCH] Revert skb_copy_datagram_iovec() recursion elimination.
4 X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/chrisw/linux-2.6.15.y.git;a=commitdiff;h=dcfd28a95dc4bb4868f867f118b4de0d0ced900c
5
6 [PATCH] Revert skb_copy_datagram_iovec() recursion elimination.
7
8 Revert the following changeset:
9
10 bc8dfcb93970ad7139c976356bfc99d7e251deaf
11
12 Recursive SKB frag lists are really possible and disallowing
13 them breaks things.
14
15 Noticed by: Jesse Brandeburg <jesse.brandeburg@intel.com>
16
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20 ---
21
22 --- a/net/core/datagram.c
23 +++ b/net/core/datagram.c
24 @@ -211,49 +211,74 @@ void skb_free_datagram(struct sock *sk,
25 int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
26 struct iovec *to, int len)
27 {
28 - int i, err, fraglen, end = 0;
29 - struct sk_buff *next = skb_shinfo(skb)->frag_list;
30 + int start = skb_headlen(skb);
31 + int i, copy = start - offset;
32
33 - if (!len)
34 - return 0;
35 + /* Copy header. */
36 + if (copy > 0) {
37 + if (copy > len)
38 + copy = len;
39 + if (memcpy_toiovec(to, skb->data + offset, copy))
40 + goto fault;
41 + if ((len -= copy) == 0)
42 + return 0;
43 + offset += copy;
44 + }
45
46 -next_skb:
47 - fraglen = skb_headlen(skb);
48 - i = -1;
49 + /* Copy paged appendix. Hmm... why does this look so complicated? */
50 + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
51 + int end;
52
53 - while (1) {
54 - int start = end;
55 + BUG_TRAP(start <= offset + len);
56
57 - if ((end += fraglen) > offset) {
58 - int copy = end - offset, o = offset - start;
59 + end = start + skb_shinfo(skb)->frags[i].size;
60 + if ((copy = end - offset) > 0) {
61 + int err;
62 + u8 *vaddr;
63 + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
64 + struct page *page = frag->page;
65
66 if (copy > len)
67 copy = len;
68 - if (i == -1)
69 - err = memcpy_toiovec(to, skb->data + o, copy);
70 - else {
71 - skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
72 - struct page *page = frag->page;
73 - void *p = kmap(page) + frag->page_offset + o;
74 - err = memcpy_toiovec(to, p, copy);
75 - kunmap(page);
76 - }
77 + vaddr = kmap(page);
78 + err = memcpy_toiovec(to, vaddr + frag->page_offset +
79 + offset - start, copy);
80 + kunmap(page);
81 if (err)
82 goto fault;
83 if (!(len -= copy))
84 return 0;
85 offset += copy;
86 }
87 - if (++i >= skb_shinfo(skb)->nr_frags)
88 - break;
89 - fraglen = skb_shinfo(skb)->frags[i].size;
90 + start = end;
91 }
92 - if (next) {
93 - skb = next;
94 - BUG_ON(skb_shinfo(skb)->frag_list);
95 - next = skb->next;
96 - goto next_skb;
97 +
98 + if (skb_shinfo(skb)->frag_list) {
99 + struct sk_buff *list = skb_shinfo(skb)->frag_list;
100 +
101 + for (; list; list = list->next) {
102 + int end;
103 +
104 + BUG_TRAP(start <= offset + len);
105 +
106 + end = start + list->len;
107 + if ((copy = end - offset) > 0) {
108 + if (copy > len)
109 + copy = len;
110 + if (skb_copy_datagram_iovec(list,
111 + offset - start,
112 + to, copy))
113 + goto fault;
114 + if ((len -= copy) == 0)
115 + return 0;
116 + offset += copy;
117 + }
118 + start = end;
119 + }
120 }
121 + if (!len)
122 + return 0;
123 +
124 fault:
125 return -EFAULT;
126 }

  ViewVC Help
Powered by ViewVC 1.1.20