linux/net/l2tp
Guillaume Nault b228a94066 l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall()
There are several ways to remove L2TP sessions:

  * deleting a session explicitly using the netlink interface (with
    L2TP_CMD_SESSION_DELETE),
  * deleting the session's parent tunnel (either by closing the
    tunnel's file descriptor or using the netlink interface),
  * closing the PPPOL2TP file descriptor of a PPP pseudo-wire.

In some cases, when these methods are used concurrently on the same
session, the session can be removed twice, leading to use-after-free
bugs.

This patch adds a 'dead' flag, used by l2tp_session_delete() and
l2tp_tunnel_closeall() to prevent them from stepping on each other's
toes.

The session deletion path used when closing a PPPOL2TP file descriptor
doesn't need to be adapted. It already has to ensure that a session
remains valid for the lifetime of its PPPOL2TP file descriptor.
So it takes an extra reference on the session in the ->session_close()
callback (pppol2tp_session_close()), which is eventually dropped
in the ->sk_destruct() callback of the PPPOL2TP socket
(pppol2tp_session_destruct()).
Still, __l2tp_session_unhash() and l2tp_session_queue_purge() can be
called twice and even concurrently for a given session, but thanks to
proper locking and re-initialisation of list fields, this is not an
issue.

Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-09-25 14:44:41 -07:00
..
Kconfig l2tp: Call udp_sock_create 2014-07-14 16:12:15 -07:00
l2tp_core.c l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() 2017-09-25 14:44:41 -07:00
l2tp_core.h l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() 2017-09-25 14:44:41 -07:00
l2tp_debugfs.c net, l2tp: convert l2tp_tunnel.ref_count from atomic_t to refcount_t 2017-07-04 22:35:15 +01:00
l2tp_eth.c l2tp: pass tunnel pointer to ->session_create() 2017-09-03 11:04:21 -07:00
l2tp_ip6.c l2tp: fix race in l2tp_recv_common() 2017-04-01 20:16:41 -07:00
l2tp_ip.c l2tp: fix race in l2tp_recv_common() 2017-04-01 20:16:41 -07:00
l2tp_netlink.c l2tp: pass tunnel pointer to ->session_create() 2017-09-03 11:04:21 -07:00
l2tp_ppp.c l2tp: ensure sessions are freed after their PPPOL2TP socket 2017-09-25 14:44:41 -07:00
Makefile l2tp: introduce L2TPv3 IP encapsulation support for IPv6 2012-05-01 09:30:55 -04:00