diff mbox series

[net] l2tp: hold tunnel in pppol2tp_connect()

Message ID 684fcf4b6a907b378274b92f033f7b78b2021809.1509381647.git.g.nault@alphalink.fr
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net] l2tp: hold tunnel in pppol2tp_connect() | expand

Commit Message

Guillaume Nault Oct. 30, 2017, 4:58 p.m. UTC
Use l2tp_tunnel_get() in pppol2tp_connect() to ensure the tunnel isn't
going to disappear while processing the rest of the function.

Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
---

Note: in case of backporting to -stable, this patch only makes sense if
f3c66d4e144a ("l2tp: prevent creation of sessions on terminated tunnels")
is already present in the tree, as we need this issue to be fixed
before fixing the current one.

The reason is that when connecting a session, we don't only depend on
the tunnel, but also on its socket. Therefore, holding a reference on
the tunnel is not enough, we also have to make sure that it's not going
to drop its socket before the session is registered.

 net/l2tp/l2tp_ppp.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

David Miller Oct. 31, 2017, 2:04 a.m. UTC | #1
From: Guillaume Nault <g.nault@alphalink.fr>
Date: Mon, 30 Oct 2017 17:58:58 +0100

> Use l2tp_tunnel_get() in pppol2tp_connect() to ensure the tunnel isn't
> going to disappear while processing the rest of the function.
> 
> Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
> Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
> ---
> 
> Note: in case of backporting to -stable, this patch only makes sense if
> f3c66d4e144a ("l2tp: prevent creation of sessions on terminated tunnels")
> is already present in the tree, as we need this issue to be fixed
> before fixing the current one.
> 
> The reason is that when connecting a session, we don't only depend on
> the tunnel, but also on its socket. Therefore, holding a reference on
> the tunnel is not enough, we also have to make sure that it's not going
> to drop its socket before the session is registered.

Applied and thank you for the detailed -stable explanation, it really
helps.
diff mbox series

Patch

diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index f50452b919d5..0c2738349442 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -584,6 +584,7 @@  static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	u32 tunnel_id, peer_tunnel_id;
 	u32 session_id, peer_session_id;
 	bool drop_refcnt = false;
+	bool drop_tunnel = false;
 	int ver = 2;
 	int fd;
 
@@ -652,7 +653,9 @@  static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	if (tunnel_id == 0)
 		goto end;
 
-	tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
+	tunnel = l2tp_tunnel_get(sock_net(sk), tunnel_id);
+	if (tunnel)
+		drop_tunnel = true;
 
 	/* Special case: create tunnel context if session_id and
 	 * peer_session_id is 0. Otherwise look up tunnel using supplied
@@ -781,6 +784,8 @@  static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
 end:
 	if (drop_refcnt)
 		l2tp_session_dec_refcount(session);
+	if (drop_tunnel)
+		l2tp_tunnel_dec_refcount(tunnel);
 	release_sock(sk);
 
 	return error;