Patch "l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups
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-take-remote-address-into-account-in-l2tp_ip-and-l2tp_ip6-socket-lookups.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 Wed Dec 6 17:39:55 CET 2017
From: Guillaume Nault <[email protected]>
Date: Fri, 30 Dec 2016 19:48:20 +0100
Subject: l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups
From: Guillaume Nault <[email protected]>
[ Upstream commit a9b2dff80be979432484afaf7f8d8e73f9e8838a ]
For connected sockets, __l2tp_ip{,6}_bind_lookup() needs to check the remote IP when looking for a matching socket. Otherwise a connected socket can receive traffic not originating from its peer.
Drop l2tp_ip_bind_lookup() and l2tp_ip6_bind_lookup() instead of updating their prototype, as these functions aren't used.
--- net/l2tp/l2tp_ip.c | 19 ++++++------------- net/l2tp/l2tp_ip6.c | 20 ++++++-------------- 2 files changed, 12 insertions(+), 27 deletions(-)
net/l2tp/l2tp_ip.c +6 -13
@@ -48,7 +48,8 @@ static inline struct l2tp_ip_sock *l2tp_return (struct l2tp_ip_sock *)sk; } -static struct sock *__l2tp_ip_bind_lookup (struct net *net,__be32 laddr,int dif,u32 tunnel_id) +static struct sock *__l2tp_ip_bind_lookup (const struct net *net,__be32 laddr, +__be32 raddr,int dif,u32 tunnel_id) {struct sock *sk;
@@ -62,6 +63,7 @@ static struct sock *__l2tp_ip_bind_lookuif ((l2tp->conn_id == tunnel_id) &&net_eq (sock_net (sk), net) && !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && + (!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) && (!sk->sk_bound_dev_if || !dif || sk->sk_bound_dev_if == dif)) goto found;
@@ -72,15 +74,6 @@ found:return sk; } -static inline struct sock *l2tp_ip_bind_lookup (struct net *net,__be32 laddr,int dif,u32 tunnel_id) -{ -struct sock *sk =__l2tp_ip_bind_lookup (net, laddr, dif, tunnel_id); -if (sk) -sock_hold (sk); - -return sk; -} -/* When processing receive frames, there are two cases to * consider. Data frames consist of a non-zero session-id and an * optional cookie. Control frames consist of a regular L2TP header
@@ -186,8 +179,8 @@ pass_up:struct iphdr *iph = (struct iphdr *)skb_network_header (skb);read_lock_bh (&l2tp_ip_lock); - sk =__l2tp_ip_bind_lookup (net, iph->daddr,inet_iif (skb), - tunnel_id); + 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;
@@ -289,7 +282,7 @@ static int l2tp_ip_bind(struct sock *sk, inet->inet_saddr =0 ;/* Use device */ write_lock_bh (&l2tp_ip_lock); -if (__l2tp_ip_bind_lookup (net, addr->l2tp_addr.s_addr, +if (__l2tp_ip_bind_lookup (net, addr->l2tp_addr.s_addr,0 , sk->sk_bound_dev_if, addr->l2tp_conn_id)) {write_unlock_bh (&l2tp_ip_lock); ret = -EADDRINUSE ;
net/l2tp/l2tp_ip6.c +6 -14
@@ -59,12 +59,14 @@ static inline struct l2tp_ip6_sock *l2tpstatic struct sock *__l2tp_ip6_bind_lookup (struct net *net,struct in6_addr *laddr, +const struct in6_addr *raddr,int dif,u32 tunnel_id) {struct sock *sk;sk_for_each_bound (sk, &l2tp_ip6_bind_table) {const struct in6_addr *sk_laddr =inet6_rcv_saddr (sk); +const struct in6_addr *sk_raddr = &sk->sk_v6_daddr;struct l2tp_ip6_sock *l2tp =l2tp_ip6_sk (sk);if (l2tp ==NULL )
@@ -73,6 +75,7 @@ static struct sock *__l2tp_ip6_bind_lookif ((l2tp->conn_id == tunnel_id) &&net_eq (sock_net (sk), net) && (!sk_laddr ||ipv6_addr_any (sk_laddr) ||ipv6_addr_equal (sk_laddr, laddr)) && + (!raddr ||ipv6_addr_any (sk_raddr) ||ipv6_addr_equal (sk_raddr, raddr)) && (!sk->sk_bound_dev_if || !dif || sk->sk_bound_dev_if == dif)) goto found;
@@ -83,17 +86,6 @@ found:return sk; } -static inline struct sock *l2tp_ip6_bind_lookup (struct net *net, -struct in6_addr *laddr, -int dif,u32 tunnel_id) -{ -struct sock *sk =__l2tp_ip6_bind_lookup (net, laddr, dif, tunnel_id); -if (sk) -sock_hold (sk); - -return sk; -} -/* When processing receive frames, there are two cases to * consider. Data frames consist of a non-zero session-id and an * optional cookie. Control frames consist of a regular L2TP header
@@ -200,8 +192,8 @@ pass_up:struct ipv6hdr *iph =ipv6_hdr (skb);read_lock_bh (&l2tp_ip6_lock); - sk =__l2tp_ip6_bind_lookup (net, &iph->daddr,inet6_iif (skb), - tunnel_id); + 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;
@@ -339,7 +331,7 @@ static int l2tp_ip6_bind(struct sock *skrcu_read_unlock ();write_lock_bh (&l2tp_ip6_lock); -if (__l2tp_ip6_bind_lookup (net, &addr->l2tp_addr, bound_dev_if, +if (__l2tp_ip6_bind_lookup (net, &addr->l2tp_addr,NULL , bound_dev_if, addr->l2tp_conn_id)) {write_unlock_bh (&l2tp_ip6_lock); err = -EADDRINUSE ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/l2tp-take-remote-address-into-account-in-l2tp_ip-and-l2tp_ip6-socket-lookups.patch