aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_core.h
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2017-09-01 17:58:48 +0200
committerDavid S. Miller <davem@davemloft.net>2017-09-03 11:04:21 -0700
commitf3c66d4e144a0904ea9b95d23ed9f8eb38c11bfb (patch)
treef77f3808a53201c80c72a9fcf71cd41a088b99a7 /net/l2tp/l2tp_core.h
parentMerge branch 'net-revert-lib-percpu_counter-API-for-fragmentation-mem-accounting' (diff)
downloadlinux-dev-f3c66d4e144a0904ea9b95d23ed9f8eb38c11bfb.tar.xz
linux-dev-f3c66d4e144a0904ea9b95d23ed9f8eb38c11bfb.zip
l2tp: prevent creation of sessions on terminated tunnels
l2tp_tunnel_destruct() sets tunnel->sock to NULL, then removes the tunnel from the pernet list and finally closes all its sessions. Therefore, it's possible to add a session to a tunnel that is still reachable, but for which tunnel->sock has already been reset. This can make l2tp_session_create() dereference a NULL pointer when calling sock_hold(tunnel->sock). This patch adds the .acpt_newsess field to struct l2tp_tunnel, which is used by l2tp_tunnel_closeall() to prevent addition of new sessions to tunnels. Resetting tunnel->sock is done after l2tp_tunnel_closeall() returned, so that l2tp_session_add_to_tunnel() can safely take a reference on it when .acpt_newsess is true. The .acpt_newsess field is modified in l2tp_tunnel_closeall(), rather than in l2tp_tunnel_destruct(), so that it benefits all tunnel removal mechanisms. E.g. on UDP tunnels, a session could be added to a tunnel after l2tp_udp_encap_destroy() proceeded. This would prevent the tunnel from being removed because of the references held by this new session on the tunnel and its socket. Even though the session could be removed manually later on, this defeats the purpose of commit 9980d001cec8 ("l2tp: add udp encap socket destroy handler"). Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_core.h')
-rw-r--r--net/l2tp/l2tp_core.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 9101297f27ad..4593d48df953 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -162,6 +162,10 @@ struct l2tp_tunnel {
int magic; /* Should be L2TP_TUNNEL_MAGIC */
struct rcu_head rcu;
rwlock_t hlist_lock; /* protect session_hlist */
+ bool acpt_newsess; /* Indicates whether this
+ * tunnel accepts new sessions.
+ * Protected by hlist_lock.
+ */
struct hlist_head session_hlist[L2TP_HASH_SIZE];
/* hashed list of sessions,
* hashed by id */