Skip to content

Commit 7f6afc3

Browse files
committed
Merge branch 'l2tp-fixes'
Guillaume Nault says: ==================== l2tp: pppol2tp_connect() fixes This series fixes a few remaining issues with pppol2tp_connect(). It doesn't try to prevent invalid configurations that have no effect on kernel's reliability. That would be work for a future patch set. Patch 2 is the most important as it avoids an invalid pointer dereference crashing the kernel. It depends on patch 1 for correctly identifying L2TP session types. Patches 3 and 4 avoid creating stale tunnels and sessions. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents aeddb6d + bda06be commit 7f6afc3

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

net/l2tp/l2tp_ppp.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
612612
u32 session_id, peer_session_id;
613613
bool drop_refcnt = false;
614614
bool drop_tunnel = false;
615+
bool new_session = false;
616+
bool new_tunnel = false;
615617
int ver = 2;
616618
int fd;
617619

@@ -701,6 +703,15 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
701703
.encap = L2TP_ENCAPTYPE_UDP,
702704
.debug = 0,
703705
};
706+
707+
/* Prevent l2tp_tunnel_register() from trying to set up
708+
* a kernel socket.
709+
*/
710+
if (fd < 0) {
711+
error = -EBADF;
712+
goto end;
713+
}
714+
704715
error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
705716
if (error < 0)
706717
goto end;
@@ -713,6 +724,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
713724
goto end;
714725
}
715726
drop_tunnel = true;
727+
new_tunnel = true;
716728
}
717729
} else {
718730
/* Error if we can't find the tunnel */
@@ -734,6 +746,12 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
734746
session = l2tp_session_get(sock_net(sk), tunnel, session_id);
735747
if (session) {
736748
drop_refcnt = true;
749+
750+
if (session->pwtype != L2TP_PWTYPE_PPP) {
751+
error = -EPROTOTYPE;
752+
goto end;
753+
}
754+
737755
ps = l2tp_session_priv(session);
738756

739757
/* Using a pre-existing session is fine as long as it hasn't
@@ -751,6 +769,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
751769
/* Default MTU must allow space for UDP/L2TP/PPP headers */
752770
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
753771
cfg.mru = cfg.mtu;
772+
cfg.pw_type = L2TP_PWTYPE_PPP;
754773

755774
session = l2tp_session_create(sizeof(struct pppol2tp_session),
756775
tunnel, session_id,
@@ -772,6 +791,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
772791
goto end;
773792
}
774793
drop_refcnt = true;
794+
new_session = true;
775795
}
776796

777797
/* Special case: if source & dest session_id == 0x0000, this
@@ -818,6 +838,12 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
818838
session->name);
819839

820840
end:
841+
if (error) {
842+
if (new_session)
843+
l2tp_session_delete(session);
844+
if (new_tunnel)
845+
l2tp_tunnel_delete(tunnel);
846+
}
821847
if (drop_refcnt)
822848
l2tp_session_dec_refcount(session);
823849
if (drop_tunnel)

0 commit comments

Comments
 (0)