]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fix sk_forward_alloc underflow, from Herbert.
authorChris Wright <chrisw@osdl.org>
Fri, 2 Sep 2005 04:59:47 +0000 (21:59 -0700)
committerChris Wright <chrisw@osdl.org>
Fri, 2 Sep 2005 04:59:47 +0000 (21:59 -0700)
queue/fix-sk_forward_alloc-underflow-in-tcp_sendmsg.patch [new file with mode: 0644]
queue/series

diff --git a/queue/fix-sk_forward_alloc-underflow-in-tcp_sendmsg.patch b/queue/fix-sk_forward_alloc-underflow-in-tcp_sendmsg.patch
new file mode 100644 (file)
index 0000000..8616d53
--- /dev/null
@@ -0,0 +1,75 @@
+From stable-bounces@linux.kernel.org  Thu Sep  1 18:03:15 2005
+Date: Fri, 2 Sep 2005 11:02:57 +1000
+To: stable@kernel.org
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S. Miller" <davem@davemloft.net>
+Subject: [stable] [TCP] Fix sk_forward_alloc underflow in tcp_sendmsg
+
+This patch fixes an sk_forward_alloc underflow in the TCP stack.
+The underflow could potentially cause assertion failures and other
+unhealthy symptoms.
+
+When tcp_sendmsg tacks on extra bits to an existing TCP_PAGE we don't
+check sk_forward_alloc even though a large amount of time may have
+elapsed since we allocated the page.  In the mean time someone could've
+come along and liberated packets and reclaimed sk_forward_alloc memory.
+
+This patch makes tcp_sendmsg check sk_forward_alloc every time as we
+do in do_tcp_sendpages.
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+---
+ include/net/sock.h |    5 ++---
+ net/ipv4/tcp.c     |   14 +++++++++-----
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+Index: linux-2.6.13.y/include/net/sock.h
+===================================================================
+--- linux-2.6.13.y.orig/include/net/sock.h
++++ linux-2.6.13.y/include/net/sock.h
+@@ -1178,9 +1178,8 @@ static inline struct page *sk_stream_all
+ {
+       struct page *page = NULL;
+-      if (sk_stream_wmem_schedule(sk, PAGE_SIZE))
+-              page = alloc_pages(sk->sk_allocation, 0);
+-      else {
++      page = alloc_pages(sk->sk_allocation, 0);
++      if (!page) {
+               sk->sk_prot->enter_memory_pressure();
+               sk_stream_moderate_sndbuf(sk);
+       }
+Index: linux-2.6.13.y/net/ipv4/tcp.c
+===================================================================
+--- linux-2.6.13.y.orig/net/ipv4/tcp.c
++++ linux-2.6.13.y/net/ipv4/tcp.c
+@@ -882,19 +882,23 @@ new_segment:
+                                       if (off == PAGE_SIZE) {
+                                               put_page(page);
+                                               TCP_PAGE(sk) = page = NULL;
++                                              TCP_OFF(sk) = off = 0;
+                                       }
+-                              }
++                              } else
++                                      BUG_ON(off);
++
++                              if (copy > PAGE_SIZE - off)
++                                      copy = PAGE_SIZE - off;
++
++                              if (!sk_stream_wmem_schedule(sk, copy))
++                                      goto wait_for_memory;
+                               if (!page) {
+                                       /* Allocate new cache page. */
+                                       if (!(page = sk_stream_alloc_page(sk)))
+                                               goto wait_for_memory;
+-                                      off = 0;
+                               }
+-                              if (copy > PAGE_SIZE - off)
+-                                      copy = PAGE_SIZE - off;
+-
+                               /* Time to copy data. We are close to
+                                * the end! */
+                               err = skb_copy_to_page(sk, from, skb, page,
index 25b333c66a21ecaf81eb62a7d9a470b98457d0bf..b0fb337192708f22d14785337f80713eca795621 100644 (file)
@@ -1,2 +1,3 @@
 saa7134-dvb-must-select-tda1004x.patch
 aacraid-bad-BUG_ON-fix.patch
+fix-sk_forward_alloc-underflow-in-tcp_sendmsg.patch