Patch "udp: properly support MSG_PEEK with truncated buffers" has been added to the 3.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
udp: properly support MSG_PEEK with truncated buffers
to the 3.14-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:
udp-properly-support-msg_peek-with-truncated-buffers.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
197c949e7798fbf28cfadc69d9ca0c2abbf93191Mon Sep 17 00:00:00 2001
From: Eric Dumazet <[email protected]>
Date: Wed, 30 Dec 2015 08:51:12 -0500
Subject: udp: properly support MSG_PEEK with truncated buffers
From: Eric Dumazet <[email protected]>
commit 197c949e7798fbf28cfadc69d9ca0c2abbf93191 upstream.
Backport of this upstream commit into stable kernels :89c22d8c3b27 ("net: Fix skb csum races when peeking") exposed a bug in udp stack vs MSG_PEEK support, when user provides a buffer smaller than skb payload.
In this case, skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov);
returns -EFAULT.
This bug does not happen in upstream kernels since Al Viro did a great job to replace this into :skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg); This variant is safe vs short buffers.
For the time being, instead reverting Herbert Xu patch and add back skb->ip_summed invalid changes, simply store the result of udp_lib_checksum_complete() so that we avoid computing the checksum a second time, and avoid the problematic skb_copy_and_csum_datagram_iovec() call.
This patch can be applied on recent kernels as it avoids a double checksumming, then backported to stable kernels as a bug fix.
--- net/ipv4/udp.c | 6 ++++-- net/ipv6/udp.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-)
net/ipv4/udp.c +4 -2
@@ -1233,6 +1233,7 @@ int udp_recvmsg(struct kiocb *iocb, struint peeked, off =0 ;int err;int is_udplite =IS_UDPLITE (sk); +bool checksum_valid = false;bool slow;if (flags &MSG_ERRQUEUE )
@@ -1258,11 +1259,12 @@ try_again:*/ if (copied < ulen ||UDP_SKB_CB (skb)->partial_cov) { -if (udp_lib_checksum_complete (skb)) + checksum_valid = !udp_lib_checksum_complete (skb); +if (!checksum_valid) goto csum_copy_err; } -if (skb_csum_unnecessary (skb)) +if (checksum_valid ||skb_csum_unnecessary (skb)) err =skb_copy_datagram_iovec (skb,sizeof (struct udphdr ), msg->msg_iov, copied);else {
net/ipv6/udp.c +4 -2
@@ -389,6 +389,7 @@ int udpv6_recvmsg(struct kiocb *iocb, stint peeked, off =0 ;int err;int is_udplite =IS_UDPLITE (sk); +bool checksum_valid = false;int is_udp4;bool slow;
@@ -420,11 +421,12 @@ try_again:*/ if (copied < ulen ||UDP_SKB_CB (skb)->partial_cov) { -if (udp_lib_checksum_complete (skb)) + checksum_valid = !udp_lib_checksum_complete (skb); +if (!checksum_valid) goto csum_copy_err; } -if (skb_csum_unnecessary (skb)) +if (checksum_valid ||skb_csum_unnecessary (skb)) err =skb_copy_datagram_iovec (skb,sizeof (struct udphdr ), msg->msg_iov, copied);else {
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/tcp_acks_speedup.patch queue-3.14/udp-properly-support-msg_peek-with-truncated-buffers.patch