mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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: 309795f4be
("l2tp: Add netlink control API for L2TP")
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4e4b21da3a
commit
e702c1204e
@ -518,8 +518,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
||||
tunnel = l2tp_tunnel_find(net, tunnel_id);
|
||||
tunnel = l2tp_tunnel_get(net, tunnel_id);
|
||||
if (!tunnel) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
@ -527,24 +528,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
||||
|
||||
if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
|
||||
|
||||
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
|
||||
|
||||
if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
|
||||
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
|
||||
if (tunnel->version > 2) {
|
||||
@ -566,7 +567,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
||||
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
|
||||
if (len > 8) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
cfg.cookie_len = len;
|
||||
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
|
||||
u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
|
||||
if (len > 8) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
cfg.peer_cookie_len = len;
|
||||
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
|
||||
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
|
||||
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
|
||||
ret = -EPROTONOSUPPORT;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
|
||||
/* 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
|
||||
case L2TP_PWTYPE_ETH_VLAN:
|
||||
if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
goto out_tunnel;
|
||||
}
|
||||
break;
|
||||
case L2TP_PWTYPE_ETH:
|
||||
@ -656,6 +657,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
||||
}
|
||||
}
|
||||
|
||||
out_tunnel:
|
||||
l2tp_tunnel_dec_refcount(tunnel);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user