| From: Guillaume Nault <g.nault@alphalink.fr> |
| Date: Wed, 13 Jun 2018 15:09:19 +0200 |
| Subject: l2tp: only accept PPP sessions in pppol2tp_connect() |
| |
| commit 7ac6ab1f8a38ba7f8d97f95475bb6a2575db4658 upstream. |
| |
| l2tp_session_priv() returns a struct pppol2tp_session pointer only for |
| PPPoL2TP sessions. In particular, if the session is an L2TP_PWTYPE_ETH |
| pseudo-wire, l2tp_session_priv() returns a pointer to an l2tp_eth_sess |
| structure, which is much smaller than struct pppol2tp_session. This |
| leads to invalid memory dereference when trying to lock ps->sk_lock. |
| |
| Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") |
| Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/l2tp/l2tp_ppp.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/net/l2tp/l2tp_ppp.c |
| +++ b/net/l2tp/l2tp_ppp.c |
| @@ -756,6 +756,12 @@ static int pppol2tp_connect(struct socke |
| session = l2tp_session_get(sock_net(sk), tunnel, session_id, false); |
| if (session) { |
| drop_refcnt = true; |
| + |
| + if (session->pwtype != L2TP_PWTYPE_PPP) { |
| + error = -EPROTOTYPE; |
| + goto end; |
| + } |
| + |
| ps = l2tp_session_priv(session); |
| |
| /* Using a pre-existing session is fine as long as it hasn't |