aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1ab0da2632e1..e6b636d53633 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1344,22 +1344,6 @@ static void netlink_data_ready(struct sock *sk, int len)
1344 * queueing. 1344 * queueing.
1345 */ 1345 */
1346 1346
1347static void __netlink_release(struct sock *sk)
1348{
1349 /*
1350 * Last sock_put should drop referrence to sk->sk_net. It has already
1351 * been dropped in netlink_kernel_create. Taking referrence to stopping
1352 * namespace is not an option.
1353 * Take referrence to a socket to remove it from netlink lookup table
1354 * _alive_ and after that destroy it in the context of init_net.
1355 */
1356
1357 sock_hold(sk);
1358 sock_release(sk->sk_socket);
1359 sk->sk_net = get_net(&init_net);
1360 sock_put(sk);
1361}
1362
1363struct sock * 1347struct sock *
1364netlink_kernel_create(struct net *net, int unit, unsigned int groups, 1348netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1365 void (*input)(struct sk_buff *skb), 1349 void (*input)(struct sk_buff *skb),
@@ -1424,7 +1408,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1424 1408
1425out_sock_release: 1409out_sock_release:
1426 kfree(listeners); 1410 kfree(listeners);
1427 __netlink_release(sk); 1411 netlink_kernel_release(sk);
1428 return NULL; 1412 return NULL;
1429 1413
1430out_sock_release_nosk: 1414out_sock_release_nosk:
@@ -1437,10 +1421,20 @@ EXPORT_SYMBOL(netlink_kernel_create);
1437void 1421void
1438netlink_kernel_release(struct sock *sk) 1422netlink_kernel_release(struct sock *sk)
1439{ 1423{
1424 /*
1425 * Last sock_put should drop referrence to sk->sk_net. It has already
1426 * been dropped in netlink_kernel_create. Taking referrence to stopping
1427 * namespace is not an option.
1428 * Take referrence to a socket to remove it from netlink lookup table
1429 * _alive_ and after that destroy it in the context of init_net.
1430 */
1440 if (sk == NULL || sk->sk_socket == NULL) 1431 if (sk == NULL || sk->sk_socket == NULL)
1441 return; 1432 return;
1442 1433
1443 __netlink_release(sk); 1434 sock_hold(sk);
1435 sock_release(sk->sk_socket);
1436 sk->sk_net = get_net(&init_net);
1437 sock_put(sk);
1444} 1438}
1445EXPORT_SYMBOL(netlink_kernel_release); 1439EXPORT_SYMBOL(netlink_kernel_release);
1446 1440