This is a note to let you know that I've just added the patch titled tcp: fix potential huge kmalloc() calls in TCP_REPAIR to the 4.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: tcp-fix-potential-huge-kmalloc-calls-in-tcp_repair.patch and it can be found in the queue-4.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Fri Dec 11 11:39:13 EST 2015 From: Eric Dumazet <edumazet@xxxxxxxxxx> Date: Wed, 18 Nov 2015 21:03:33 -0800 Subject: tcp: fix potential huge kmalloc() calls in TCP_REPAIR From: Eric Dumazet <edumazet@xxxxxxxxxx> [ Upstream commit 5d4c9bfbabdb1d497f21afd81501e5c54b0c85d9 ] tcp_send_rcvq() is used for re-injecting data into tcp receive queue. Problems : - No check against size is performed, allowed user to fool kernel in attempting very large memory allocations, eventually triggering OOM when memory is fragmented. - In case of fault during the copy we do not return correct errno. Lets use alloc_skb_with_frags() to cook optimal skbs. Fixes: 292e8d8c8538 ("tcp: Move rcvq sending to tcp_input.c") Fixes: c0e88ff0f256 ("tcp: Repair socket queues") Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx> Cc: Pavel Emelyanov <xemul@xxxxxxxxxxxxx> Acked-by: Pavel Emelyanov <xemul@xxxxxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/ipv4/tcp_input.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4438,19 +4438,34 @@ static int __must_check tcp_queue_rcv(st int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) { struct sk_buff *skb; + int err = -ENOMEM; + int data_len = 0; bool fragstolen; if (size == 0) return 0; - skb = alloc_skb(size, sk->sk_allocation); + if (size > PAGE_SIZE) { + int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS); + + data_len = npages << PAGE_SHIFT; + size = data_len + (size & ~PAGE_MASK); + } + skb = alloc_skb_with_frags(size - data_len, data_len, + PAGE_ALLOC_COSTLY_ORDER, + &err, sk->sk_allocation); if (!skb) goto err; + skb_put(skb, size - data_len); + skb->data_len = data_len; + skb->len = size; + if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) goto err_free; - if (memcpy_from_msg(skb_put(skb, size), msg, size)) + err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); + if (err) goto err_free; TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; @@ -4466,7 +4481,8 @@ int tcp_send_rcvq(struct sock *sk, struc err_free: kfree_skb(skb); err: - return -ENOMEM; + return err; + } static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) Patches currently in stable-queue which might be from edumazet@xxxxxxxxxx are queue-4.1/ipv6-add-complete-rcu-protection-around-np-opt.patch queue-4.1/packet-infer-protocol-from-ethernet-header-if-unset.patch queue-4.1/ipv6-sctp-implement-sctp_v6_destroy_sock.patch queue-4.1/tcp-disable-fast-open-on-timeouts-after-handshake.patch queue-4.1/net-scm-fix-pax-detected-msg_controllen-overflow-in-scm_detach_fds.patch queue-4.1/tcp-md5-fix-lockdep-annotation.patch queue-4.1/net_sched-fix-qdisc_tree_decrease_qlen-races.patch queue-4.1/tcp-initialize-tp-copied_seq-in-case-of-cross-syn-connection.patch queue-4.1/tcp-fix-potential-huge-kmalloc-calls-in-tcp_repair.patch queue-4.1/packet-do-skb_probe_transport_header-when-we-actually-have-data.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html