Commit d70ff6fd authored by David S. Miller's avatar David S. Miller

[TCP]: Do not underflow sk_forward_alloc in sendpage().

We need to do the proper checks before we try to
pull space out of it, just like sendmsg() does.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 62343f76
...@@ -655,7 +655,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse ...@@ -655,7 +655,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
while (psize > 0) { while (psize > 0) {
struct sk_buff *skb = sk->sk_write_queue.prev; struct sk_buff *skb = sk->sk_write_queue.prev;
struct page *page = pages[poffset / PAGE_SIZE]; struct page *page = pages[poffset / PAGE_SIZE];
int copy, i; int copy, i, can_coalesce;
int offset = poffset % PAGE_SIZE; int offset = poffset % PAGE_SIZE;
int size = min_t(size_t, psize, PAGE_SIZE - offset); int size = min_t(size_t, psize, PAGE_SIZE - offset);
...@@ -677,14 +677,20 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse ...@@ -677,14 +677,20 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
copy = size; copy = size;
i = skb_shinfo(skb)->nr_frags; i = skb_shinfo(skb)->nr_frags;
if (skb_can_coalesce(skb, i, page, offset)) { can_coalesce = skb_can_coalesce(skb, i, page, offset);
if (!can_coalesce && i >= MAX_SKB_FRAGS) {
tcp_mark_push(tp, skb);
goto new_segment;
}
if (sk->sk_forward_alloc < copy &&
!sk_stream_mem_schedule(sk, copy, 0))
goto wait_for_memory;
if (can_coalesce) {
skb_shinfo(skb)->frags[i - 1].size += copy; skb_shinfo(skb)->frags[i - 1].size += copy;
} else if (i < MAX_SKB_FRAGS) { } else {
get_page(page); get_page(page);
skb_fill_page_desc(skb, i, page, offset, copy); skb_fill_page_desc(skb, i, page, offset, copy);
} else {
tcp_mark_push(tp, skb);
goto new_segment;
} }
skb->len += copy; skb->len += copy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment