| From 94d7ee0baa8b764cf64ad91ed69464c1a6a0066b Mon Sep 17 00:00:00 2001 |
| From: Guillaume Nault <g.nault@alphalink.fr> |
| Date: Wed, 29 Mar 2017 08:44:59 +0200 |
| Subject: [PATCH] l2tp: hold tunnel socket when handling control frames in |
| l2tp_ip and l2tp_ip6 |
| |
| commit 94d7ee0baa8b764cf64ad91ed69464c1a6a0066b upstream. |
| |
| The code following l2tp_tunnel_find() expects that a new reference is |
| held on sk. Either sk_receive_skb() or the discard_put error path will |
| drop a reference from the tunnel's socket. |
| |
| This issue exists in both l2tp_ip and l2tp_ip6. |
| |
| Fixes: a3c18422a4b4 ("l2tp: hold socket before dropping lock in l2tp_ip{, 6}_recv()") |
| Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| |
| diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c |
| index d25038cfd64e..7208fbe5856b 100644 |
| --- a/net/l2tp/l2tp_ip.c |
| +++ b/net/l2tp/l2tp_ip.c |
| @@ -178,9 +178,10 @@ pass_up: |
| |
| tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
| tunnel = l2tp_tunnel_find(net, tunnel_id); |
| - if (tunnel != NULL) |
| + if (tunnel) { |
| sk = tunnel->sock; |
| - else { |
| + sock_hold(sk); |
| + } else { |
| struct iphdr *iph = (struct iphdr *) skb_network_header(skb); |
| |
| read_lock_bh(&l2tp_ip_lock); |
| diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c |
| index a4abcbc4c09a..516d7ce24ba7 100644 |
| --- a/net/l2tp/l2tp_ip6.c |
| +++ b/net/l2tp/l2tp_ip6.c |
| @@ -191,9 +191,10 @@ pass_up: |
| |
| tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
| tunnel = l2tp_tunnel_find(net, tunnel_id); |
| - if (tunnel != NULL) |
| + if (tunnel) { |
| sk = tunnel->sock; |
| - else { |
| + sock_hold(sk); |
| + } else { |
| struct ipv6hdr *iph = ipv6_hdr(skb); |
| |
| read_lock_bh(&l2tp_ip6_lock); |
| -- |
| 2.12.0 |
| |