aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netlink.h4
-rw-r--r--include/net/genetlink.h4
-rw-r--r--kernel/audit.c2
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netlink/af_netlink.c21
-rw-r--r--net/netlink/af_netlink.h8
-rw-r--r--net/netlink/genetlink.c12
7 files changed, 28 insertions, 25 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 9e572daa15d5..02fc86d2348e 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -46,8 +46,8 @@ struct netlink_kernel_cfg {
46 unsigned int flags; 46 unsigned int flags;
47 void (*input)(struct sk_buff *skb); 47 void (*input)(struct sk_buff *skb);
48 struct mutex *cb_mutex; 48 struct mutex *cb_mutex;
49 int (*bind)(int group); 49 int (*bind)(struct net *net, int group);
50 void (*unbind)(int group); 50 void (*unbind)(struct net *net, int group);
51 bool (*compare)(struct net *net, struct sock *sk); 51 bool (*compare)(struct net *net, struct sock *sk);
52}; 52};
53 53
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 3ed31e5a445b..84125088c309 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -56,8 +56,8 @@ struct genl_family {
56 void (*post_doit)(const struct genl_ops *ops, 56 void (*post_doit)(const struct genl_ops *ops,
57 struct sk_buff *skb, 57 struct sk_buff *skb,
58 struct genl_info *info); 58 struct genl_info *info);
59 int (*mcast_bind)(int group); 59 int (*mcast_bind)(struct net *net, int group);
60 void (*mcast_unbind)(int group); 60 void (*mcast_unbind)(struct net *net, int group);
61 struct nlattr ** attrbuf; /* private */ 61 struct nlattr ** attrbuf; /* private */
62 const struct genl_ops * ops; /* private */ 62 const struct genl_ops * ops; /* private */
63 const struct genl_multicast_group *mcgrps; /* private */ 63 const struct genl_multicast_group *mcgrps; /* private */
diff --git a/kernel/audit.c b/kernel/audit.c
index f8f203e8018c..aba9d9fadf0c 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1100,7 +1100,7 @@ static void audit_receive(struct sk_buff *skb)
1100} 1100}
1101 1101
1102/* Run custom bind function on netlink socket group connect or bind requests. */ 1102/* Run custom bind function on netlink socket group connect or bind requests. */
1103static int audit_bind(int group) 1103static int audit_bind(struct net *net, int group)
1104{ 1104{
1105 if (!capable(CAP_AUDIT_READ)) 1105 if (!capable(CAP_AUDIT_READ))
1106 return -EPERM; 1106 return -EPERM;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 13c2e17bbe27..cde4a6702fa3 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -463,7 +463,7 @@ static void nfnetlink_rcv(struct sk_buff *skb)
463} 463}
464 464
465#ifdef CONFIG_MODULES 465#ifdef CONFIG_MODULES
466static int nfnetlink_bind(int group) 466static int nfnetlink_bind(struct net *net, int group)
467{ 467{
468 const struct nfnetlink_subsystem *ss; 468 const struct nfnetlink_subsystem *ss;
469 int type; 469 int type;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index f29b63fad932..84ea76ca3f1f 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1141,8 +1141,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
1141 struct module *module = NULL; 1141 struct module *module = NULL;
1142 struct mutex *cb_mutex; 1142 struct mutex *cb_mutex;
1143 struct netlink_sock *nlk; 1143 struct netlink_sock *nlk;
1144 int (*bind)(int group); 1144 int (*bind)(struct net *net, int group);
1145 void (*unbind)(int group); 1145 void (*unbind)(struct net *net, int group);
1146 int err = 0; 1146 int err = 0;
1147 1147
1148 sock->state = SS_UNCONNECTED; 1148 sock->state = SS_UNCONNECTED;
@@ -1251,7 +1251,7 @@ static int netlink_release(struct socket *sock)
1251 1251
1252 for (i = 0; i < nlk->ngroups; i++) 1252 for (i = 0; i < nlk->ngroups; i++)
1253 if (test_bit(i, nlk->groups)) 1253 if (test_bit(i, nlk->groups))
1254 nlk->netlink_unbind(i + 1); 1254 nlk->netlink_unbind(sock_net(sk), i + 1);
1255 } 1255 }
1256 kfree(nlk->groups); 1256 kfree(nlk->groups);
1257 nlk->groups = NULL; 1257 nlk->groups = NULL;
@@ -1418,8 +1418,9 @@ static int netlink_realloc_groups(struct sock *sk)
1418} 1418}
1419 1419
1420static void netlink_undo_bind(int group, long unsigned int groups, 1420static void netlink_undo_bind(int group, long unsigned int groups,
1421 struct netlink_sock *nlk) 1421 struct sock *sk)
1422{ 1422{
1423 struct netlink_sock *nlk = nlk_sk(sk);
1423 int undo; 1424 int undo;
1424 1425
1425 if (!nlk->netlink_unbind) 1426 if (!nlk->netlink_unbind)
@@ -1427,7 +1428,7 @@ static void netlink_undo_bind(int group, long unsigned int groups,
1427 1428
1428 for (undo = 0; undo < group; undo++) 1429 for (undo = 0; undo < group; undo++)
1429 if (test_bit(undo, &groups)) 1430 if (test_bit(undo, &groups))
1430 nlk->netlink_unbind(undo); 1431 nlk->netlink_unbind(sock_net(sk), undo);
1431} 1432}
1432 1433
1433static int netlink_bind(struct socket *sock, struct sockaddr *addr, 1434static int netlink_bind(struct socket *sock, struct sockaddr *addr,
@@ -1465,10 +1466,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
1465 for (group = 0; group < nlk->ngroups; group++) { 1466 for (group = 0; group < nlk->ngroups; group++) {
1466 if (!test_bit(group, &groups)) 1467 if (!test_bit(group, &groups))
1467 continue; 1468 continue;
1468 err = nlk->netlink_bind(group); 1469 err = nlk->netlink_bind(net, group);
1469 if (!err) 1470 if (!err)
1470 continue; 1471 continue;
1471 netlink_undo_bind(group, groups, nlk); 1472 netlink_undo_bind(group, groups, sk);
1472 return err; 1473 return err;
1473 } 1474 }
1474 } 1475 }
@@ -1478,7 +1479,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
1478 netlink_insert(sk, net, nladdr->nl_pid) : 1479 netlink_insert(sk, net, nladdr->nl_pid) :
1479 netlink_autobind(sock); 1480 netlink_autobind(sock);
1480 if (err) { 1481 if (err) {
1481 netlink_undo_bind(nlk->ngroups, groups, nlk); 1482 netlink_undo_bind(nlk->ngroups, groups, sk);
1482 return err; 1483 return err;
1483 } 1484 }
1484 } 1485 }
@@ -2129,7 +2130,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2129 if (!val || val - 1 >= nlk->ngroups) 2130 if (!val || val - 1 >= nlk->ngroups)
2130 return -EINVAL; 2131 return -EINVAL;
2131 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { 2132 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
2132 err = nlk->netlink_bind(val); 2133 err = nlk->netlink_bind(sock_net(sk), val);
2133 if (err) 2134 if (err)
2134 return err; 2135 return err;
2135 } 2136 }
@@ -2138,7 +2139,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2138 optname == NETLINK_ADD_MEMBERSHIP); 2139 optname == NETLINK_ADD_MEMBERSHIP);
2139 netlink_table_ungrab(); 2140 netlink_table_ungrab();
2140 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) 2141 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
2141 nlk->netlink_unbind(val); 2142 nlk->netlink_unbind(sock_net(sk), val);
2142 2143
2143 err = 0; 2144 err = 0;
2144 break; 2145 break;
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index b20a1731759b..f123a88496f8 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -39,8 +39,8 @@ struct netlink_sock {
39 struct mutex *cb_mutex; 39 struct mutex *cb_mutex;
40 struct mutex cb_def_mutex; 40 struct mutex cb_def_mutex;
41 void (*netlink_rcv)(struct sk_buff *skb); 41 void (*netlink_rcv)(struct sk_buff *skb);
42 int (*netlink_bind)(int group); 42 int (*netlink_bind)(struct net *net, int group);
43 void (*netlink_unbind)(int group); 43 void (*netlink_unbind)(struct net *net, int group);
44 struct module *module; 44 struct module *module;
45#ifdef CONFIG_NETLINK_MMAP 45#ifdef CONFIG_NETLINK_MMAP
46 struct mutex pg_vec_lock; 46 struct mutex pg_vec_lock;
@@ -65,8 +65,8 @@ struct netlink_table {
65 unsigned int groups; 65 unsigned int groups;
66 struct mutex *cb_mutex; 66 struct mutex *cb_mutex;
67 struct module *module; 67 struct module *module;
68 int (*bind)(int group); 68 int (*bind)(struct net *net, int group);
69 void (*unbind)(int group); 69 void (*unbind)(struct net *net, int group);
70 bool (*compare)(struct net *net, struct sock *sock); 70 bool (*compare)(struct net *net, struct sock *sock);
71 int registered; 71 int registered;
72}; 72};
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 05bf40bbd189..91566ed36c43 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -983,7 +983,7 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
983 { .name = "notify", }, 983 { .name = "notify", },
984}; 984};
985 985
986static int genl_bind(int group) 986static int genl_bind(struct net *net, int group)
987{ 987{
988 int i, err; 988 int i, err;
989 bool found = false; 989 bool found = false;
@@ -997,8 +997,10 @@ static int genl_bind(int group)
997 group < f->mcgrp_offset + f->n_mcgrps) { 997 group < f->mcgrp_offset + f->n_mcgrps) {
998 int fam_grp = group - f->mcgrp_offset; 998 int fam_grp = group - f->mcgrp_offset;
999 999
1000 if (f->mcast_bind) 1000 if (!f->netnsok && net != &init_net)
1001 err = f->mcast_bind(fam_grp); 1001 err = -ENOENT;
1002 else if (f->mcast_bind)
1003 err = f->mcast_bind(net, fam_grp);
1002 else 1004 else
1003 err = 0; 1005 err = 0;
1004 found = true; 1006 found = true;
@@ -1014,7 +1016,7 @@ static int genl_bind(int group)
1014 return err; 1016 return err;
1015} 1017}
1016 1018
1017static void genl_unbind(int group) 1019static void genl_unbind(struct net *net, int group)
1018{ 1020{
1019 int i; 1021 int i;
1020 bool found = false; 1022 bool found = false;
@@ -1029,7 +1031,7 @@ static void genl_unbind(int group)
1029 int fam_grp = group - f->mcgrp_offset; 1031 int fam_grp = group - f->mcgrp_offset;
1030 1032
1031 if (f->mcast_unbind) 1033 if (f->mcast_unbind)
1032 f->mcast_unbind(fam_grp); 1034 f->mcast_unbind(net, fam_grp);
1033 found = true; 1035 found = true;
1034 break; 1036 break;
1035 } 1037 }