Skip to contentSkip to conversation

Patch "l2tp: do not use udp_ioctl()" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Feb 15, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

l2tp: do not use udp_ioctl()

to the 4.9-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:
l2tp-do-not-use-udp_ioctl.patch
and it can be found in the queue-4.9 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 Tue Feb 14 17:03:08 PST 2017

From: Eric Dumazet <[email protected]>
Date: Thu, 9 Feb 2017 16:15:52 -0800
Subject: l2tp: do not use udp_ioctl()

From: Eric Dumazet <[email protected]>

[ Upstream commit 72fb96e7bdbbdd4421b0726992496531060f3636 ]

udp_ioctl(), as its name suggests, is used by UDP protocols, but is also used by L2TP :(

L2TP should use its own handler, because it really does not look the same.

SIOCINQ for instance should not assume UDP checksum or headers.

Thanks to Andrey and syzkaller team for providing the report and a nice reproducer.

While crashes only happen on recent kernels (after commit 7c13f97ffde6 ("udp: do fwd memory scheduling on dequeue")), this probably needs to be backported to older kernels.

Fixes 7c13f97ffde6 ("udp: do fwd memory scheduling on dequeue")
Fixes 85584672012e ("udp: Fix udp_poll() and ioctl()")
---
 net/l2tp/l2tp_core.h |    1 +
 net/l2tp/l2tp_ip.c   |   27 ++++++++++++++++++++++++++-
 net/l2tp/l2tp_ip6.c  |    2 +-
 3 files changed, 28 insertions(+), 2 deletions(-)
net/l2tp/l2tp_core.h +1 -0
@@ -273,6 +273,7 @@ int l2tp_xmit_skb(struct l2tp_session *s
 int l2tp_nl_register_ops(enum l2tp_pwtype pw_type,
 			 const struct l2tp_nl_cmd_ops *ops);
 void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 
 /* Session reference counts. Incremented when code obtains a reference
  * to a session.
net/l2tp/l2tp_ip.c +26 -1
@@ -11,6 +11,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <asm/ioctls.h>
 #include <linux/icmp.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -560,6 +561,30 @@ out:
 	return err ? err : copied;
 }
 
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+	struct sk_buff *skb;
+	int amount;
+
+	switch (cmd) {
+	case SIOCOUTQ:
+		amount = sk_wmem_alloc_get(sk);
+		break;
+	case SIOCINQ:
+		spin_lock_bh(&sk->sk_receive_queue.lock);
+		skb = skb_peek(&sk->sk_receive_queue);
+		amount = skb ? skb->len : 0;
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return put_user(amount, (int __user *)arg);
+}
+EXPORT_SYMBOL(l2tp_ioctl);
+
 static struct proto l2tp_ip_prot = {
 	.name		   = "L2TP/IP",
 	.owner		   = THIS_MODULE,
@@ -568,7 +593,7 @@ static struct proto l2tp_ip_prot = {
 	.bind		   = l2tp_ip_bind,
 	.connect	   = l2tp_ip_connect,
 	.disconnect	   = l2tp_ip_disconnect,
-	.ioctl		   = udp_ioctl,
+	.ioctl		   = l2tp_ioctl,
 	.destroy	   = l2tp_ip_destroy_sock,
 	.setsockopt	   = ip_setsockopt,
 	.getsockopt	   = ip_getsockopt,
net/l2tp/l2tp_ip6.c +1 -1
@@ -729,7 +729,7 @@ static struct proto l2tp_ip6_prot = {
 	.bind		   = l2tp_ip6_bind,
 	.connect	   = l2tp_ip6_connect,
 	.disconnect	   = l2tp_ip6_disconnect,
-	.ioctl		   = udp_ioctl,
+	.ioctl		   = l2tp_ioctl,
 	.destroy	   = l2tp_ip6_destroy_sock,
 	.setsockopt	   = ipv6_setsockopt,
 	.getsockopt	   = ipv6_getsockopt,

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/ipv6-pointer-math-error-in-ip6_tnl_parse_tlv_enc_lim.patch queue-4.9/netlabel-out-of-bound-access-in-cipso_v4_validate.patch queue-4.9/packet-round-up-linear-to-header-len.patch queue-4.9/tun-read-vnet_hdr_sz-once.patch queue-4.9/ipv6-fix-ip6_tnl_parse_tlv_enc_lim.patch queue-4.9/l2tp-do-not-use-udp_ioctl.patch queue-4.9/tcp-fix-0-divide-in-__tcp_select_window.patch queue-4.9/can-fix-kernel-panic-at-security_sock_rcv_skb.patch queue-4.9/net-introduce-device-min_header_len.patch queue-4.9/macvtap-read-vnet_hdr_size-once.patch queue-4.9/tcp-avoid-infinite-loop-in-tcp_splice_read.patch queue-4.9/mlx4-invoke-softirqs-after-napi_reschedule.patch queue-4.9/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch queue-4.9/ipv4-keep-skb-dst-around-in-presence-of-ip-options.patch queue-4.9/net-use-a-work-queue-to-defer-net_disable_timestamp-work.patch queue-4.9/ip6_gre-fix-ip6gre_err-invalid-reads.patch