From 8d5672d1068ca6193b5107db64f522b89a04eabb Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Mon, 13 Feb 2006 17:10:35 -0800 Subject: [PATCH] Revert skb_copy_datagram_iovec recursion patch, from DaveM --- ...datagram_iovec-recursion-elimination.patch | 128 ++++++++++++++++++ queue/series | 1 + 2 files changed, 129 insertions(+) create mode 100644 queue/revert-skb_copy_datagram_iovec-recursion-elimination.patch diff --git a/queue/revert-skb_copy_datagram_iovec-recursion-elimination.patch b/queue/revert-skb_copy_datagram_iovec-recursion-elimination.patch new file mode 100644 index 00000000000..7745582c8b7 --- /dev/null +++ b/queue/revert-skb_copy_datagram_iovec-recursion-elimination.patch @@ -0,0 +1,128 @@ +From stable-bounces@linux.kernel.org Mon Feb 13 16:49:33 2006 +Date: Mon, 13 Feb 2006 16:46:25 -0800 (PST) +From: "David S. Miller" +To: stable@kernel.org +Cc: +Subject: [NET]: Revert skb_copy_datagram_iovec() recursion elimination. + +Revert the following changeset: + +bc8dfcb93970ad7139c976356bfc99d7e251deaf + +Recursive SKB frag lists are really possible and disallowing +them breaks things. + +Noticed by: Jesse Brandeburg + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + + net/core/datagram.c | 81 ++++++++++++++++++++++++++++++++++------------------ + 1 files changed, 53 insertions(+), 28 deletions(-) + +--- linux-2.6.15.4.orig/net/core/datagram.c ++++ linux-2.6.15.4/net/core/datagram.c +@@ -211,49 +211,74 @@ void skb_free_datagram(struct sock *sk, + int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, + struct iovec *to, int len) + { +- int i, err, fraglen, end = 0; +- struct sk_buff *next = skb_shinfo(skb)->frag_list; ++ int start = skb_headlen(skb); ++ int i, copy = start - offset; + +- if (!len) +- return 0; ++ /* Copy header. */ ++ if (copy > 0) { ++ if (copy > len) ++ copy = len; ++ if (memcpy_toiovec(to, skb->data + offset, copy)) ++ goto fault; ++ if ((len -= copy) == 0) ++ return 0; ++ offset += copy; ++ } + +-next_skb: +- fraglen = skb_headlen(skb); +- i = -1; ++ /* Copy paged appendix. Hmm... why does this look so complicated? */ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ int end; + +- while (1) { +- int start = end; ++ BUG_TRAP(start <= offset + len); + +- if ((end += fraglen) > offset) { +- int copy = end - offset, o = offset - start; ++ end = start + skb_shinfo(skb)->frags[i].size; ++ if ((copy = end - offset) > 0) { ++ int err; ++ u8 *vaddr; ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ struct page *page = frag->page; + + if (copy > len) + copy = len; +- if (i == -1) +- err = memcpy_toiovec(to, skb->data + o, copy); +- else { +- skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; +- struct page *page = frag->page; +- void *p = kmap(page) + frag->page_offset + o; +- err = memcpy_toiovec(to, p, copy); +- kunmap(page); +- } ++ vaddr = kmap(page); ++ err = memcpy_toiovec(to, vaddr + frag->page_offset + ++ offset - start, copy); ++ kunmap(page); + if (err) + goto fault; + if (!(len -= copy)) + return 0; + offset += copy; + } +- if (++i >= skb_shinfo(skb)->nr_frags) +- break; +- fraglen = skb_shinfo(skb)->frags[i].size; ++ start = end; + } +- if (next) { +- skb = next; +- BUG_ON(skb_shinfo(skb)->frag_list); +- next = skb->next; +- goto next_skb; ++ ++ if (skb_shinfo(skb)->frag_list) { ++ struct sk_buff *list = skb_shinfo(skb)->frag_list; ++ ++ for (; list; list = list->next) { ++ int end; ++ ++ BUG_TRAP(start <= offset + len); ++ ++ end = start + list->len; ++ if ((copy = end - offset) > 0) { ++ if (copy > len) ++ copy = len; ++ if (skb_copy_datagram_iovec(list, ++ offset - start, ++ to, copy)) ++ goto fault; ++ if ((len -= copy) == 0) ++ return 0; ++ offset += copy; ++ } ++ start = end; ++ } + } ++ if (!len) ++ return 0; ++ + fault: + return -EFAULT; + } diff --git a/queue/series b/queue/series index d550294aace..9f4e8a59c2d 100644 --- a/queue/series +++ b/queue/series @@ -5,3 +5,4 @@ netfilter-missing-symbol.patch i386-move-phys_proc_id-early-intel-workaround-to-correct-function.patch hugetlbfs-mmap-enomem-failure.patch reiserfs-disable-automatic-enabling-of-reiserfs-inode-attributes.patch +revert-skb_copy_datagram_iovec-recursion-elimination.patch -- 2.47.3