Patch "l2tp: don't use l2tp_tunnel_find() in l2tp_ip and l2tp_ip6" has been added to the 4.13-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
l2tp: don't use l2tp_tunnel_find() in l2tp_ip and l2tp_ip6
to the 4.13-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-don-t-use-l2tp_tunnel_find-in-l2tp_ip-and-l2tp_ip6.patch
and it can be found in the queue-4.13 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 Nov 21 13:07:20 CET 2017
From: Guillaume Nault <[email protected]>
Date: Fri, 3 Nov 2017 16:49:00 +0100
Subject: l2tp: don't use l2tp_tunnel_find() in l2tp_ip and l2tp_ip6
From: Guillaume Nault <[email protected]>
[ Upstream commit 8f7dc9ae4a7aece9fbc3e6637bdfa38b36bcdf09 ]
Using l2tp_tunnel_find() in l2tp_ip_recv() is wrong for two reasons:
* It doesn't take a reference on the returned tunnel, which makes the call racy wrt. concurrent tunnel deletion.
* The lookup is only based on the tunnel identifier, so it can return a tunnel that doesn't match the packet's addresses or protocol.
For example, a packet sent to an L2TPv3 over IPv6 tunnel can be delivered to an L2TPv2 over UDPv4 tunnel. This is worse than a simple
cross-talk: when delivering the packet to an L2TP over UDP tunnel, the corresponding socket is UDP, where ->sk_backlog_rcv() is NULL. Calling sk_receive_skb() will then crash the kernel by trying to execute this callback.
And l2tp_tunnel_find() isn't even needed here. __l2tp_ip_bind_lookup() properly checks the socket binding and connection settings. It was used as a fallback mechanism for finding tunnels that didn't have their data path registered yet. But it's not limited to this case and can be used to replace l2tp_tunnel_find() in the general case.
Fix l2tp_ip6 in the same way.
--- net/l2tp/l2tp_ip.c | 24 +++++++++--------------- net/l2tp/l2tp_ip6.c | 24 +++++++++--------------- 2 files changed, 18 insertions(+), 30 deletions(-)
net/l2tp/l2tp_ip.c +9 -15
@@ -123,6 +123,7 @@ static int l2tp_ip_recv(struct sk_buff *unsigned char *ptr, *optr;struct l2tp_session *session;struct l2tp_tunnel *tunnel =NULL ; +struct iphdr *iph;int length;if (!pskb_may_pull (skb,4 ))
@@ -178,24 +179,17 @@ pass_up: goto discard; tunnel_id =ntohl (*(__be32 *) &skb->data[4 ]); - tunnel =l2tp_tunnel_find (net, tunnel_id); -if (tunnel) { - sk = tunnel->sock; -sock_hold (sk); - }else { -struct iphdr *iph = (struct iphdr *)skb_network_header (skb); - -read_lock_bh (&l2tp_ip_lock); - sk =__l2tp_ip_bind_lookup (net, iph->daddr, iph->saddr, -inet_iif (skb), tunnel_id); -if (!sk) { -read_unlock_bh (&l2tp_ip_lock); - goto discard; - } + iph = (struct iphdr *)skb_network_header (skb); -sock_hold (sk); +read_lock_bh (&l2tp_ip_lock); + sk =__l2tp_ip_bind_lookup (net, iph->daddr, iph->saddr,inet_iif (skb), + tunnel_id); +if (!sk) {read_unlock_bh (&l2tp_ip_lock); + goto discard; } +sock_hold (sk); +read_unlock_bh (&l2tp_ip_lock);if (!xfrm4_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_put;
net/l2tp/l2tp_ip6.c +9 -15
@@ -136,6 +136,7 @@ static int l2tp_ip6_recv(struct sk_buffunsigned char *ptr, *optr;struct l2tp_session *session;struct l2tp_tunnel *tunnel =NULL ; +struct ipv6hdr *iph;int length;if (!pskb_may_pull (skb,4 ))
@@ -192,24 +193,17 @@ pass_up: goto discard; tunnel_id =ntohl (*(__be32 *) &skb->data[4 ]); - tunnel =l2tp_tunnel_find (net, tunnel_id); -if (tunnel) { - sk = tunnel->sock; -sock_hold (sk); - }else { -struct ipv6hdr *iph =ipv6_hdr (skb); - -read_lock_bh (&l2tp_ip6_lock); - sk =__l2tp_ip6_bind_lookup (net, &iph->daddr, &iph->saddr, -inet6_iif (skb), tunnel_id); -if (!sk) { -read_unlock_bh (&l2tp_ip6_lock); - goto discard; - } + iph =ipv6_hdr (skb); -sock_hold (sk); +read_lock_bh (&l2tp_ip6_lock); + sk =__l2tp_ip6_bind_lookup (net, &iph->daddr, &iph->saddr, +inet6_iif (skb), tunnel_id); +if (!sk) {read_unlock_bh (&l2tp_ip6_lock); + goto discard; } +sock_hold (sk); +read_unlock_bh (&l2tp_ip6_lock);if (!xfrm6_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_put;
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/l2tp-don-t-use-l2tp_tunnel_find-in-l2tp_ip-and-l2tp_ip6.patch