Patch "tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs" has been added to the 4.10-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs
to the 4.10-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-scm_timestamping_opt_stats-for-normal-skbs.patch
and it can be found in the queue-4.10 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 foo@baz Sat Apr 29 08:22:40 CEST 2017
From: Soheil Hassas Yeganeh <[email protected]>
Date: Sat, 18 Mar 2017 17:02:59 -0400
Subject: tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs
From: Soheil Hassas Yeganeh <[email protected]>
[ Upstream commit 8605330aac5a5785630aec8f64378a54891937cc ]
__sock_recv_timestamp can be called for both normal skbs (for receive timestamps) and for skbs on the error queue (for transmit timestamps).
Commit 1c885808e456
(tcp: SOF_TIMESTAMPING_OPT_STATS option for SO_TIMESTAMPING) assumes any skb passed to __sock_recv_timestamp are from the error queue, containing OPT_STATS in the content of the skb. This results in accessing invalid memory or generating junk data.
To fix this, set skb->pkt_type to PACKET_OUTGOING for packets on the error queue. This is safe because on the receive path on local sockets skb->pkt_type is never set to PACKET_OUTGOING. With that, copy OPT_STATS from a packet, only if its pkt_type is PACKET_OUTGOING.
--- net/core/skbuff.c | 10 ++++++++++ net/socket.c | 13 ++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-)
net/core/skbuff.c +10 -0
@@ -3700,6 +3700,15 @@ static void sock_rmem_free(struct sk_bufatomic_sub (skb->truesize, &sk->sk_rmem_alloc); } +static void skb_set_err_queue (struct sk_buff *skb) +{ +/* pkt_type of skbs received on local sockets is never PACKET_OUTGOING. +* So, it is safe to (mis)use it to mark skbs on the error queue. +*/ + skb->pkt_type =PACKET_OUTGOING ; +BUILD_BUG_ON (PACKET_OUTGOING ==0 ); +} +/* * Note: We dont mem charge error packets (no sk_forward_alloc changes) */
@@ -3713,6 +3722,7 @@ int sock_queue_err_skb(struct sock *sk, skb->sk = sk; skb->destructor = sock_rmem_free;atomic_add (skb->truesize, &sk->sk_rmem_alloc); +skb_set_err_queue (skb);/* before exiting rcu section, make sure dst is refcounted */ skb_dst_force (skb);
net/socket.c +12 -1
@@ -654,6 +654,16 @@ int kernel_sendmsg(struct socket *sock, }EXPORT_SYMBOL (kernel_sendmsg); +static bool skb_is_err_queue (const struct sk_buff *skb) +{ +/* pkt_type of skbs enqueued on the error queue are set to +* PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do +* in recvmsg, since skbs received on a local socket will never +* have a pkt_type of PACKET_OUTGOING. +*/ +return skb->pkt_type ==PACKET_OUTGOING ; +} +/* * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) */
@@ -697,7 +707,8 @@ void __sock_recv_timestamp(struct msghdrput_cmsg (msg,SOL_SOCKET ,SCM_TIMESTAMPING ,sizeof (tss), &tss); -if (skb->len && (sk->sk_tsflags &SOF_TIMESTAMPING_OPT_STATS )) +if (skb_is_err_queue (skb) && skb->len && + (sk->sk_tsflags &SOF_TIMESTAMPING_OPT_STATS ))put_cmsg (msg,SOL_SOCKET ,SCM_TIMESTAMPING_OPT_STATS , skb->len, skb->data); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/tcp-mark-skbs-with-scm_timestamping_opt_stats.patch queue-4.10/secure_seq-downgrade-to-per-host-timestamp-offsets.patch queue-4.10/tcp-fix-scm_timestamping_opt_stats-for-normal-skbs.patch