l2tp: l2tp_ppp must ignore non-PPP sessions
Subsystems (3)
cover l2tp: l2tp_ppp must ignore non-PPP sessions
The original L2TP code was written for version 2 of the protocol, which could only carry PPP sessions. Then L2TPv3 generalised the protocol so that it could transport different kinds of pseudo-wires. But parts of the l2tp_ppp module still break in presence of non-PPP sessions.
Assuming L2TPv2 tunnels can only transport PPP sessions is right, but l2tp_netlink failed to ensure that (fixed in patch 1). When retrieving a session from an arbitrary tunnel, l2tp_ppp needs to filter out non-PPP sessions (last occurrence fixed in patch 2).
Guillaume Nault (2):
l2tp: reject creation of non-PPP sessions on L2TPv2 tunnels
l2tp: filter out non-PPP sessions in pppol2tp_tunnel_ioctl()
net/l2tp/l2tp_netlink.c | 6 ++++++ net/l2tp/l2tp_ppp.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
Signature · 1 line
2.17.1
PATCH 1/2 l2tp: reject creation of non-PPP sessions on L2TPv2 tunnels
The /proc/net/pppol2tp handlers (pppol2tp_seq_*()) iterate over all L2TPv2 tunnels, and rightfully expect that only PPP sessions can be found there. However, l2tp_netlink accepts creating Ethernet sessions regardless of the underlying tunnel version.
This confuses pppol2tp_seq_session_show(), which expects that l2tp_session_priv() returns a pppol2tp_session structure. When the session is an Ethernet pseudo-wire, a struct l2tp_eth_sess is returned instead. This leads to invalid memory access when pppol2tp_session_get_sock() later tries to dereference ps->sk.
--- net/l2tp/l2tp_netlink.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/l2tp/l2tp_netlink.c +6 -0
@@ -553,6 +553,12 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf goto out_tunnel; } +/* L2TPv2 only accepts PPP pseudo-wires */ +if (tunnel->version ==2 && cfg.pw_type !=L2TP_PWTYPE_PPP ) { + ret = -EPROTONOSUPPORT ; + goto out_tunnel; + } +if (tunnel->version >2 ) {if (info->attrs[L2TP_ATTR_DATA_SEQ ]) cfg.data_seq =nla_get_u8 (info->attrs[L2TP_ATTR_DATA_SEQ ]);
Signature · 1 line
2.17.1
PATCH 2/2 l2tp: filter out non-PPP sessions in pppol2tp_tunnel_ioctl()
In reply to Guillaume Naultpppol2tp_tunnel_ioctl() can act on an L2TPv3 tunnel, in which case 'session' may be an Ethernet pseudo-wire.
However, pppol2tp_session_ioctl() expects a PPP pseudo-wire, as it assumes l2tp_session_priv() points to a pppol2tp_session structure. For an Ethernet pseudo-wire l2tp_session_priv() points to an l2tp_eth_sess structure instead, making pppol2tp_session_ioctl() access invalid memory.
--- net/l2tp/l2tp_ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/l2tp/l2tp_ppp.c +1 -1
@@ -1201,7 +1201,7 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel,l2tp_session_get (sock_net (sk), tunnel, stats.session_id); -if (session) { +if (session && session->pwtype ==L2TP_PWTYPE_PPP ) { err =pppol2tp_session_ioctl (session, cmd, arg);l2tp_session_dec_refcount (session);
Signature · 1 line
2.17.1
David Miller
maintainerFrom: Guillaume Nault <[email protected]>
Date: Fri, 15 Jun 2018 15:39:15 +0200
Quoted 9 lines
The original L2TP code was written for version 2 of the protocol, which could only carry PPP sessions. Then L2TPv3 generalised the protocol so that it could transport different kinds of pseudo-wires. But parts of the
l2tp_pppmodule still break in presence of non-PPP sessions.Assuming L2TPv2 tunnels can only transport PPP sessions is right, but
l2tp_netlinkfailed to ensure that (fixed in patch 1). When retrieving a session from an arbitrary tunnel,l2tp_pppneeds to filter out non-PPP sessions (last occurrence fixed in patch 2).
Series applied, thank you.