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 <davem@davemloft.net>
This commit is contained in:
commit
7f6afc3384
@ -612,6 +612,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
u32 session_id, peer_session_id;
|
u32 session_id, peer_session_id;
|
||||||
bool drop_refcnt = false;
|
bool drop_refcnt = false;
|
||||||
bool drop_tunnel = false;
|
bool drop_tunnel = false;
|
||||||
|
bool new_session = false;
|
||||||
|
bool new_tunnel = false;
|
||||||
int ver = 2;
|
int ver = 2;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -701,6 +703,15 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
.encap = L2TP_ENCAPTYPE_UDP,
|
.encap = L2TP_ENCAPTYPE_UDP,
|
||||||
.debug = 0,
|
.debug = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Prevent l2tp_tunnel_register() from trying to set up
|
||||||
|
* a kernel socket.
|
||||||
|
*/
|
||||||
|
if (fd < 0) {
|
||||||
|
error = -EBADF;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
|
error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto end;
|
goto end;
|
||||||
@ -713,6 +724,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
drop_tunnel = true;
|
drop_tunnel = true;
|
||||||
|
new_tunnel = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Error if we can't find the tunnel */
|
/* Error if we can't find the tunnel */
|
||||||
@ -734,6 +746,12 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
session = l2tp_session_get(sock_net(sk), tunnel, session_id);
|
session = l2tp_session_get(sock_net(sk), tunnel, session_id);
|
||||||
if (session) {
|
if (session) {
|
||||||
drop_refcnt = true;
|
drop_refcnt = true;
|
||||||
|
|
||||||
|
if (session->pwtype != L2TP_PWTYPE_PPP) {
|
||||||
|
error = -EPROTOTYPE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
ps = l2tp_session_priv(session);
|
ps = l2tp_session_priv(session);
|
||||||
|
|
||||||
/* Using a pre-existing session is fine as long as it hasn't
|
/* 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,
|
|||||||
/* Default MTU must allow space for UDP/L2TP/PPP headers */
|
/* Default MTU must allow space for UDP/L2TP/PPP headers */
|
||||||
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
|
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
|
||||||
cfg.mru = cfg.mtu;
|
cfg.mru = cfg.mtu;
|
||||||
|
cfg.pw_type = L2TP_PWTYPE_PPP;
|
||||||
|
|
||||||
session = l2tp_session_create(sizeof(struct pppol2tp_session),
|
session = l2tp_session_create(sizeof(struct pppol2tp_session),
|
||||||
tunnel, session_id,
|
tunnel, session_id,
|
||||||
@ -772,6 +791,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
drop_refcnt = true;
|
drop_refcnt = true;
|
||||||
|
new_session = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case: if source & dest session_id == 0x0000, this
|
/* Special case: if source & dest session_id == 0x0000, this
|
||||||
@ -818,6 +838,12 @@ out_no_ppp:
|
|||||||
session->name);
|
session->name);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
if (error) {
|
||||||
|
if (new_session)
|
||||||
|
l2tp_session_delete(session);
|
||||||
|
if (new_tunnel)
|
||||||
|
l2tp_tunnel_delete(tunnel);
|
||||||
|
}
|
||||||
if (drop_refcnt)
|
if (drop_refcnt)
|
||||||
l2tp_session_dec_refcount(session);
|
l2tp_session_dec_refcount(session);
|
||||||
if (drop_tunnel)
|
if (drop_tunnel)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user