Skip to content

Commit 0c84cee

Browse files
committed
Merge branch 'l2tp-tunnel-creation-fixes'
Guillaume Nault says: ==================== l2tp: tunnel creation fixes L2TP tunnel creation is racy. We need to make sure that the tunnel returned by l2tp_tunnel_create() isn't going to be freed while the caller is using it. This is done in patch #1, by separating tunnel creation from tunnel registration. With the tunnel registration code in place, we can now check for duplicate tunnels in a race-free way. This is done in patch #2, which incidentally removes the last use of l2tp_tunnel_find(). ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 83c1f36 + f6cd651 commit 0c84cee

File tree

4 files changed

+123
-137
lines changed

4 files changed

+123
-137
lines changed

net/l2tp/l2tp_core.c

Lines changed: 98 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -335,26 +335,6 @@ int l2tp_session_register(struct l2tp_session *session,
335335
}
336336
EXPORT_SYMBOL_GPL(l2tp_session_register);
337337

338-
/* Lookup a tunnel by id
339-
*/
340-
struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id)
341-
{
342-
struct l2tp_tunnel *tunnel;
343-
struct l2tp_net *pn = l2tp_pernet(net);
344-
345-
rcu_read_lock_bh();
346-
list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
347-
if (tunnel->tunnel_id == tunnel_id) {
348-
rcu_read_unlock_bh();
349-
return tunnel;
350-
}
351-
}
352-
rcu_read_unlock_bh();
353-
354-
return NULL;
355-
}
356-
EXPORT_SYMBOL_GPL(l2tp_tunnel_find);
357-
358338
struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
359339
{
360340
struct l2tp_net *pn = l2tp_pernet(net);
@@ -1436,74 +1416,11 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
14361416
{
14371417
struct l2tp_tunnel *tunnel = NULL;
14381418
int err;
1439-
struct socket *sock = NULL;
1440-
struct sock *sk = NULL;
1441-
struct l2tp_net *pn;
14421419
enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP;
14431420

1444-
/* Get the tunnel socket from the fd, which was opened by
1445-
* the userspace L2TP daemon. If not specified, create a
1446-
* kernel socket.
1447-
*/
1448-
if (fd < 0) {
1449-
err = l2tp_tunnel_sock_create(net, tunnel_id, peer_tunnel_id,
1450-
cfg, &sock);
1451-
if (err < 0)
1452-
goto err;
1453-
} else {
1454-
sock = sockfd_lookup(fd, &err);
1455-
if (!sock) {
1456-
pr_err("tunl %u: sockfd_lookup(fd=%d) returned %d\n",
1457-
tunnel_id, fd, err);
1458-
err = -EBADF;
1459-
goto err;
1460-
}
1461-
1462-
/* Reject namespace mismatches */
1463-
if (!net_eq(sock_net(sock->sk), net)) {
1464-
pr_err("tunl %u: netns mismatch\n", tunnel_id);
1465-
err = -EINVAL;
1466-
goto err;
1467-
}
1468-
}
1469-
1470-
sk = sock->sk;
1471-
14721421
if (cfg != NULL)
14731422
encap = cfg->encap;
14741423

1475-
/* Quick sanity checks */
1476-
err = -EPROTONOSUPPORT;
1477-
if (sk->sk_type != SOCK_DGRAM) {
1478-
pr_debug("tunl %hu: fd %d wrong socket type\n",
1479-
tunnel_id, fd);
1480-
goto err;
1481-
}
1482-
switch (encap) {
1483-
case L2TP_ENCAPTYPE_UDP:
1484-
if (sk->sk_protocol != IPPROTO_UDP) {
1485-
pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1486-
tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
1487-
goto err;
1488-
}
1489-
break;
1490-
case L2TP_ENCAPTYPE_IP:
1491-
if (sk->sk_protocol != IPPROTO_L2TP) {
1492-
pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1493-
tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
1494-
goto err;
1495-
}
1496-
break;
1497-
}
1498-
1499-
/* Check if this socket has already been prepped */
1500-
tunnel = l2tp_tunnel(sk);
1501-
if (tunnel != NULL) {
1502-
/* This socket has already been prepped */
1503-
err = -EBUSY;
1504-
goto err;
1505-
}
1506-
15071424
tunnel = kzalloc(sizeof(struct l2tp_tunnel), GFP_KERNEL);
15081425
if (tunnel == NULL) {
15091426
err = -ENOMEM;
@@ -1520,72 +1437,126 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
15201437
rwlock_init(&tunnel->hlist_lock);
15211438
tunnel->acpt_newsess = true;
15221439

1523-
/* The net we belong to */
1524-
tunnel->l2tp_net = net;
1525-
pn = l2tp_pernet(net);
1526-
15271440
if (cfg != NULL)
15281441
tunnel->debug = cfg->debug;
15291442

1530-
/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
15311443
tunnel->encap = encap;
1532-
if (encap == L2TP_ENCAPTYPE_UDP) {
1533-
struct udp_tunnel_sock_cfg udp_cfg = { };
1534-
1535-
udp_cfg.sk_user_data = tunnel;
1536-
udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP;
1537-
udp_cfg.encap_rcv = l2tp_udp_encap_recv;
1538-
udp_cfg.encap_destroy = l2tp_udp_encap_destroy;
1539-
1540-
setup_udp_tunnel_sock(net, sock, &udp_cfg);
1541-
} else {
1542-
sk->sk_user_data = tunnel;
1543-
}
15441444

1545-
/* Bump the reference count. The tunnel context is deleted
1546-
* only when this drops to zero. A reference is also held on
1547-
* the tunnel socket to ensure that it is not released while
1548-
* the tunnel is extant. Must be done before sk_destruct is
1549-
* set.
1550-
*/
15511445
refcount_set(&tunnel->ref_count, 1);
1552-
sock_hold(sk);
1553-
tunnel->sock = sk;
15541446
tunnel->fd = fd;
15551447

1556-
/* Hook on the tunnel socket destructor so that we can cleanup
1557-
* if the tunnel socket goes away.
1558-
*/
1559-
tunnel->old_sk_destruct = sk->sk_destruct;
1560-
sk->sk_destruct = &l2tp_tunnel_destruct;
1561-
lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
1562-
1563-
sk->sk_allocation = GFP_ATOMIC;
1564-
15651448
/* Init delete workqueue struct */
15661449
INIT_WORK(&tunnel->del_work, l2tp_tunnel_del_work);
15671450

1568-
/* Add tunnel to our list */
15691451
INIT_LIST_HEAD(&tunnel->list);
1570-
spin_lock_bh(&pn->l2tp_tunnel_list_lock);
1571-
list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
1572-
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
15731452

15741453
err = 0;
15751454
err:
15761455
if (tunnelp)
15771456
*tunnelp = tunnel;
15781457

1579-
/* If tunnel's socket was created by the kernel, it doesn't
1580-
* have a file.
1581-
*/
1582-
if (sock && sock->file)
1583-
sockfd_put(sock);
1584-
15851458
return err;
15861459
}
15871460
EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
15881461

1462+
static int l2tp_validate_socket(const struct sock *sk, const struct net *net,
1463+
enum l2tp_encap_type encap)
1464+
{
1465+
if (!net_eq(sock_net(sk), net))
1466+
return -EINVAL;
1467+
1468+
if (sk->sk_type != SOCK_DGRAM)
1469+
return -EPROTONOSUPPORT;
1470+
1471+
if ((encap == L2TP_ENCAPTYPE_UDP && sk->sk_protocol != IPPROTO_UDP) ||
1472+
(encap == L2TP_ENCAPTYPE_IP && sk->sk_protocol != IPPROTO_L2TP))
1473+
return -EPROTONOSUPPORT;
1474+
1475+
if (sk->sk_user_data)
1476+
return -EBUSY;
1477+
1478+
return 0;
1479+
}
1480+
1481+
int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
1482+
struct l2tp_tunnel_cfg *cfg)
1483+
{
1484+
struct l2tp_tunnel *tunnel_walk;
1485+
struct l2tp_net *pn;
1486+
struct socket *sock;
1487+
struct sock *sk;
1488+
int ret;
1489+
1490+
if (tunnel->fd < 0) {
1491+
ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id,
1492+
tunnel->peer_tunnel_id, cfg,
1493+
&sock);
1494+
if (ret < 0)
1495+
goto err;
1496+
} else {
1497+
sock = sockfd_lookup(tunnel->fd, &ret);
1498+
if (!sock)
1499+
goto err;
1500+
1501+
ret = l2tp_validate_socket(sock->sk, net, tunnel->encap);
1502+
if (ret < 0)
1503+
goto err_sock;
1504+
}
1505+
1506+
sk = sock->sk;
1507+
1508+
sock_hold(sk);
1509+
tunnel->sock = sk;
1510+
tunnel->l2tp_net = net;
1511+
1512+
pn = l2tp_pernet(net);
1513+
1514+
spin_lock_bh(&pn->l2tp_tunnel_list_lock);
1515+
list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) {
1516+
if (tunnel_walk->tunnel_id == tunnel->tunnel_id) {
1517+
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
1518+
1519+
ret = -EEXIST;
1520+
goto err_sock;
1521+
}
1522+
}
1523+
list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
1524+
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
1525+
1526+
if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
1527+
struct udp_tunnel_sock_cfg udp_cfg = {
1528+
.sk_user_data = tunnel,
1529+
.encap_type = UDP_ENCAP_L2TPINUDP,
1530+
.encap_rcv = l2tp_udp_encap_recv,
1531+
.encap_destroy = l2tp_udp_encap_destroy,
1532+
};
1533+
1534+
setup_udp_tunnel_sock(net, sock, &udp_cfg);
1535+
} else {
1536+
sk->sk_user_data = tunnel;
1537+
}
1538+
1539+
tunnel->old_sk_destruct = sk->sk_destruct;
1540+
sk->sk_destruct = &l2tp_tunnel_destruct;
1541+
lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class,
1542+
"l2tp_sock");
1543+
sk->sk_allocation = GFP_ATOMIC;
1544+
1545+
if (tunnel->fd >= 0)
1546+
sockfd_put(sock);
1547+
1548+
return 0;
1549+
1550+
err_sock:
1551+
if (tunnel->fd < 0)
1552+
sock_release(sock);
1553+
else
1554+
sockfd_put(sock);
1555+
err:
1556+
return ret;
1557+
}
1558+
EXPORT_SYMBOL_GPL(l2tp_tunnel_register);
1559+
15891560
/* This function is used by the netlink TUNNEL_DELETE command.
15901561
*/
15911562
void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)

net/l2tp/l2tp_core.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,14 @@ struct l2tp_session *l2tp_session_get(const struct net *net,
220220
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
221221
struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
222222
const char *ifname);
223-
struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id);
224223
struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth);
225224

226225
int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
227226
u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
228227
struct l2tp_tunnel **tunnelp);
228+
int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
229+
struct l2tp_tunnel_cfg *cfg);
230+
229231
void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
230232
void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
231233
struct l2tp_session *l2tp_session_create(int priv_size,

net/l2tp/l2tp_netlink.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,6 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
236236
if (info->attrs[L2TP_ATTR_DEBUG])
237237
cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
238238

239-
tunnel = l2tp_tunnel_find(net, tunnel_id);
240-
if (tunnel != NULL) {
241-
ret = -EEXIST;
242-
goto out;
243-
}
244-
245239
ret = -EINVAL;
246240
switch (cfg.encap) {
247241
case L2TP_ENCAPTYPE_UDP:
@@ -251,9 +245,19 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
251245
break;
252246
}
253247

254-
if (ret >= 0)
255-
ret = l2tp_tunnel_notify(&l2tp_nl_family, info,
256-
tunnel, L2TP_CMD_TUNNEL_CREATE);
248+
if (ret < 0)
249+
goto out;
250+
251+
l2tp_tunnel_inc_refcount(tunnel);
252+
ret = l2tp_tunnel_register(tunnel, net, &cfg);
253+
if (ret < 0) {
254+
kfree(tunnel);
255+
goto out;
256+
}
257+
ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel,
258+
L2TP_CMD_TUNNEL_CREATE);
259+
l2tp_tunnel_dec_refcount(tunnel);
260+
257261
out:
258262
return ret;
259263
}

net/l2tp/l2tp_ppp.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,15 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
698698
error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
699699
if (error < 0)
700700
goto end;
701+
702+
l2tp_tunnel_inc_refcount(tunnel);
703+
error = l2tp_tunnel_register(tunnel, sock_net(sk),
704+
&tcfg);
705+
if (error < 0) {
706+
kfree(tunnel);
707+
goto end;
708+
}
709+
drop_tunnel = true;
701710
}
702711
} else {
703712
/* Error if we can't find the tunnel */

0 commit comments

Comments
 (0)