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.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 074cf3e91c6f..02fdde28dada 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -61,6 +61,7 @@
61#include <linux/rhashtable.h> 61#include <linux/rhashtable.h>
62#include <asm/cacheflush.h> 62#include <asm/cacheflush.h>
63#include <linux/hash.h> 63#include <linux/hash.h>
64#include <linux/genetlink.h>
64 65
65#include <net/net_namespace.h> 66#include <net/net_namespace.h>
66#include <net/sock.h> 67#include <net/sock.h>
@@ -1091,8 +1092,12 @@ static void netlink_remove(struct sock *sk)
1091 mutex_unlock(&nl_sk_hash_lock); 1092 mutex_unlock(&nl_sk_hash_lock);
1092 1093
1093 netlink_table_grab(); 1094 netlink_table_grab();
1094 if (nlk_sk(sk)->subscriptions) 1095 if (nlk_sk(sk)->subscriptions) {
1095 __sk_del_bind_node(sk); 1096 __sk_del_bind_node(sk);
1097 netlink_update_listeners(sk);
1098 }
1099 if (sk->sk_protocol == NETLINK_GENERIC)
1100 atomic_inc(&genl_sk_destructing_cnt);
1096 netlink_table_ungrab(); 1101 netlink_table_ungrab();
1097} 1102}
1098 1103
@@ -1139,8 +1144,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
1139 struct module *module = NULL; 1144 struct module *module = NULL;
1140 struct mutex *cb_mutex; 1145 struct mutex *cb_mutex;
1141 struct netlink_sock *nlk; 1146 struct netlink_sock *nlk;
1142 int (*bind)(int group); 1147 int (*bind)(struct net *net, int group);
1143 void (*unbind)(int group); 1148 void (*unbind)(struct net *net, int group);
1144 int err = 0; 1149 int err = 0;
1145 1150
1146 sock->state = SS_UNCONNECTED; 1151 sock->state = SS_UNCONNECTED;
@@ -1209,6 +1214,20 @@ static int netlink_release(struct socket *sock)
1209 * will be purged. 1214 * will be purged.
1210 */ 1215 */
1211 1216
1217 /* must not acquire netlink_table_lock in any way again before unbind
1218 * and notifying genetlink is done as otherwise it might deadlock
1219 */
1220 if (nlk->netlink_unbind) {
1221 int i;
1222
1223 for (i = 0; i < nlk->ngroups; i++)
1224 if (test_bit(i, nlk->groups))
1225 nlk->netlink_unbind(sock_net(sk), i + 1);
1226 }
1227 if (sk->sk_protocol == NETLINK_GENERIC &&
1228 atomic_dec_return(&genl_sk_destructing_cnt) == 0)
1229 wake_up(&genl_sk_destructing_waitq);
1230
1212 sock->sk = NULL; 1231 sock->sk = NULL;
1213 wake_up_interruptible_all(&nlk->wait); 1232 wake_up_interruptible_all(&nlk->wait);
1214 1233
@@ -1226,8 +1245,8 @@ static int netlink_release(struct socket *sock)
1226 1245
1227 module_put(nlk->module); 1246 module_put(nlk->module);
1228 1247
1229 netlink_table_grab();
1230 if (netlink_is_kernel(sk)) { 1248 if (netlink_is_kernel(sk)) {
1249 netlink_table_grab();
1231 BUG_ON(nl_table[sk->sk_protocol].registered == 0); 1250 BUG_ON(nl_table[sk->sk_protocol].registered == 0);
1232 if (--nl_table[sk->sk_protocol].registered == 0) { 1251 if (--nl_table[sk->sk_protocol].registered == 0) {
1233 struct listeners *old; 1252 struct listeners *old;
@@ -1241,10 +1260,8 @@ static int netlink_release(struct socket *sock)
1241 nl_table[sk->sk_protocol].flags = 0; 1260 nl_table[sk->sk_protocol].flags = 0;
1242 nl_table[sk->sk_protocol].registered = 0; 1261 nl_table[sk->sk_protocol].registered = 0;
1243 } 1262 }
1244 } else if (nlk->subscriptions) { 1263 netlink_table_ungrab();
1245 netlink_update_listeners(sk);
1246 } 1264 }
1247 netlink_table_ungrab();
1248 1265
1249 kfree(nlk->groups); 1266 kfree(nlk->groups);
1250 nlk->groups = NULL; 1267 nlk->groups = NULL;
@@ -1410,9 +1427,10 @@ static int netlink_realloc_groups(struct sock *sk)
1410 return err; 1427 return err;
1411} 1428}
1412 1429
1413static void netlink_unbind(int group, long unsigned int groups, 1430static void netlink_undo_bind(int group, long unsigned int groups,
1414 struct netlink_sock *nlk) 1431 struct sock *sk)
1415{ 1432{
1433 struct netlink_sock *nlk = nlk_sk(sk);
1416 int undo; 1434 int undo;
1417 1435
1418 if (!nlk->netlink_unbind) 1436 if (!nlk->netlink_unbind)
@@ -1420,7 +1438,7 @@ static void netlink_unbind(int group, long unsigned int groups,
1420 1438
1421 for (undo = 0; undo < group; undo++) 1439 for (undo = 0; undo < group; undo++)
1422 if (test_bit(undo, &groups)) 1440 if (test_bit(undo, &groups))
1423 nlk->netlink_unbind(undo); 1441 nlk->netlink_unbind(sock_net(sk), undo);
1424} 1442}
1425 1443
1426static int netlink_bind(struct socket *sock, struct sockaddr *addr, 1444static int netlink_bind(struct socket *sock, struct sockaddr *addr,
@@ -1458,10 +1476,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
1458 for (group = 0; group < nlk->ngroups; group++) { 1476 for (group = 0; group < nlk->ngroups; group++) {
1459 if (!test_bit(group, &groups)) 1477 if (!test_bit(group, &groups))
1460 continue; 1478 continue;
1461 err = nlk->netlink_bind(group); 1479 err = nlk->netlink_bind(net, group);
1462 if (!err) 1480 if (!err)
1463 continue; 1481 continue;
1464 netlink_unbind(group, groups, nlk); 1482 netlink_undo_bind(group, groups, sk);
1465 return err; 1483 return err;
1466 } 1484 }
1467 } 1485 }
@@ -1471,7 +1489,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
1471 netlink_insert(sk, net, nladdr->nl_pid) : 1489 netlink_insert(sk, net, nladdr->nl_pid) :
1472 netlink_autobind(sock); 1490 netlink_autobind(sock);
1473 if (err) { 1491 if (err) {
1474 netlink_unbind(nlk->ngroups, groups, nlk); 1492 netlink_undo_bind(nlk->ngroups, groups, sk);
1475 return err; 1493 return err;
1476 } 1494 }
1477 } 1495 }
@@ -2122,7 +2140,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2122 if (!val || val - 1 >= nlk->ngroups) 2140 if (!val || val - 1 >= nlk->ngroups)
2123 return -EINVAL; 2141 return -EINVAL;
2124 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { 2142 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
2125 err = nlk->netlink_bind(val); 2143 err = nlk->netlink_bind(sock_net(sk), val);
2126 if (err) 2144 if (err)
2127 return err; 2145 return err;
2128 } 2146 }
@@ -2131,7 +2149,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2131 optname == NETLINK_ADD_MEMBERSHIP); 2149 optname == NETLINK_ADD_MEMBERSHIP);
2132 netlink_table_ungrab(); 2150 netlink_table_ungrab();
2133 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) 2151 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
2134 nlk->netlink_unbind(val); 2152 nlk->netlink_unbind(sock_net(sk), val);
2135 2153
2136 err = 0; 2154 err = 0;
2137 break; 2155 break;