提交 e702c120 编写于 作者: G Guillaume Nault 提交者: David S. Miller

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: 309795f4 ("l2tp: Add netlink control API for L2TP")
Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 4e4b21da
...@@ -518,8 +518,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ...@@ -518,8 +518,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); 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) { if (!tunnel) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
...@@ -527,24 +528,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ...@@ -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]) { if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]); peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
if (!info->attrs[L2TP_ATTR_PW_TYPE]) { if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]); cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) { if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
if (tunnel->version > 2) { if (tunnel->version > 2) {
...@@ -566,7 +567,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ...@@ -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]); u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
if (len > 8) { if (len > 8) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
cfg.cookie_len = len; cfg.cookie_len = len;
memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), 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 ...@@ -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]); u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
if (len > 8) { if (len > 8) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
cfg.peer_cookie_len = len; cfg.peer_cookie_len = len;
memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), 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 ...@@ -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) || if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) { (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
ret = -EPROTONOSUPPORT; ret = -EPROTONOSUPPORT;
goto out; goto out_tunnel;
} }
/* Check that pseudowire-specific params are present */ /* 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 ...@@ -628,7 +629,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
case L2TP_PWTYPE_ETH_VLAN: case L2TP_PWTYPE_ETH_VLAN:
if (!info->attrs[L2TP_ATTR_VLAN_ID]) { if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_tunnel;
} }
break; break;
case L2TP_PWTYPE_ETH: case L2TP_PWTYPE_ETH:
...@@ -656,6 +657,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ...@@ -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: out:
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册