Skip to content

Commit e702c12

Browse files
Guillaume Naultdavem330
authored andcommitted
l2tp: hold tunnel used while creating sessions with netlink
Use l2tp_tunnel_get() to retrieve tunnel, so that it can't go away on us. Otherwise l2tp_tunnel_destruct() might release the last reference count concurrently, thus freeing the tunnel while we're using it. Fixes: 309795f ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4e4b21d commit e702c12

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

net/l2tp/l2tp_netlink.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -518,33 +518,34 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
518518
ret = -EINVAL;
519519
goto out;
520520
}
521+
521522
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
522-
tunnel = l2tp_tunnel_find(net, tunnel_id);
523+
tunnel = l2tp_tunnel_get(net, tunnel_id);
523524
if (!tunnel) {
524525
ret = -ENODEV;
525526
goto out;
526527
}
527528

528529
if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
529530
ret = -EINVAL;
530-
goto out;
531+
goto out_tunnel;
531532
}
532533
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
533534

534535
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
535536
ret = -EINVAL;
536-
goto out;
537+
goto out_tunnel;
537538
}
538539
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
539540

540541
if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
541542
ret = -EINVAL;
542-
goto out;
543+
goto out_tunnel;
543544
}
544545
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
545546
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
546547
ret = -EINVAL;
547-
goto out;
548+
goto out_tunnel;
548549
}
549550

550551
if (tunnel->version > 2) {
@@ -566,7 +567,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
566567
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
567568
if (len > 8) {
568569
ret = -EINVAL;
569-
goto out;
570+
goto out_tunnel;
570571
}
571572
cfg.cookie_len = len;
572573
memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
@@ -575,7 +576,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
575576
u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
576577
if (len > 8) {
577578
ret = -EINVAL;
578-
goto out;
579+
goto out_tunnel;
579580
}
580581
cfg.peer_cookie_len = len;
581582
memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
@@ -618,7 +619,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
618619
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
619620
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
620621
ret = -EPROTONOSUPPORT;
621-
goto out;
622+
goto out_tunnel;
622623
}
623624

624625
/* Check that pseudowire-specific params are present */
@@ -628,7 +629,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
628629
case L2TP_PWTYPE_ETH_VLAN:
629630
if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
630631
ret = -EINVAL;
631-
goto out;
632+
goto out_tunnel;
632633
}
633634
break;
634635
case L2TP_PWTYPE_ETH:
@@ -656,6 +657,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
656657
}
657658
}
658659

660+
out_tunnel:
661+
l2tp_tunnel_dec_refcount(tunnel);
659662
out:
660663
return ret;
661664
}

0 commit comments

Comments
 (0)