hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/net/core/net_namespace.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
34 #include <linux/workqueue.h>
....@@ -18,6 +19,7 @@
1819 #include <linux/net_namespace.h>
1920 #include <linux/sched/task.h>
2021 #include <linux/uidgid.h>
22
+#include <linux/cookie.h>
2123
2224 #include <net/sock.h>
2325 #include <net/netlink.h>
....@@ -38,9 +40,16 @@
3840 DECLARE_RWSEM(net_rwsem);
3941 EXPORT_SYMBOL_GPL(net_rwsem);
4042
43
+#ifdef CONFIG_KEYS
44
+static struct key_tag init_net_key_domain = { .usage = REFCOUNT_INIT(1) };
45
+#endif
46
+
4147 struct net init_net = {
4248 .count = REFCOUNT_INIT(1),
4349 .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head),
50
+#ifdef CONFIG_KEYS
51
+ .key_domain = &init_net_key_domain,
52
+#endif
4453 };
4554 EXPORT_SYMBOL(init_net);
4655
....@@ -60,6 +69,8 @@
6069 #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */
6170
6271 static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS;
72
+
73
+DEFINE_COOKIE(net_cookie);
6374
6475 static struct net_generic *net_alloc_generic(void)
6576 {
....@@ -112,6 +123,7 @@
112123
113124 static int ops_init(const struct pernet_operations *ops, struct net *net)
114125 {
126
+ struct net_generic *ng;
115127 int err = -ENOMEM;
116128 void *data = NULL;
117129
....@@ -130,6 +142,12 @@
130142 if (!err)
131143 return 0;
132144
145
+ if (ops->id && ops->size) {
146
+ ng = rcu_dereference_protected(net->gen,
147
+ lockdep_is_held(&pernet_ops_rwsem));
148
+ ng->ptr[*ops->id] = NULL;
149
+ }
150
+
133151 cleanup:
134152 kfree(data);
135153
....@@ -141,6 +159,17 @@
141159 {
142160 if (ops->id && ops->size) {
143161 kfree(net_generic(net, *ops->id));
162
+ }
163
+}
164
+
165
+static void ops_pre_exit_list(const struct pernet_operations *ops,
166
+ struct list_head *net_exit_list)
167
+{
168
+ struct net *net;
169
+
170
+ if (ops->pre_exit) {
171
+ list_for_each_entry(net, net_exit_list, exit_list)
172
+ ops->pre_exit(net);
144173 }
145174 }
146175
....@@ -194,16 +223,10 @@
194223 return 0;
195224 }
196225
197
-/* Must be called from RCU-critical section or with nsid_lock held. If
198
- * a new id is assigned, the bool alloc is set to true, thus the
199
- * caller knows that the new id must be notified via rtnl.
200
- */
201
-static int __peernet2id_alloc(struct net *net, struct net *peer, bool *alloc)
226
+/* Must be called from RCU-critical section or with nsid_lock held */
227
+static int __peernet2id(const struct net *net, struct net *peer)
202228 {
203229 int id = idr_for_each(&net->netns_ids, net_eq_idr, peer);
204
- bool alloc_it = *alloc;
205
-
206
- *alloc = false;
207230
208231 /* Magic value for id 0. */
209232 if (id == NET_ID_ZERO)
....@@ -211,55 +234,53 @@
211234 if (id > 0)
212235 return id;
213236
214
- if (alloc_it) {
215
- id = alloc_netid(net, peer, -1);
216
- *alloc = true;
217
- return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED;
218
- }
219
-
220237 return NETNSA_NSID_NOT_ASSIGNED;
221238 }
222239
223
-/* Must be called from RCU-critical section or with nsid_lock held */
224
-static int __peernet2id(struct net *net, struct net *peer)
225
-{
226
- bool no = false;
227
-
228
- return __peernet2id_alloc(net, peer, &no);
229
-}
230
-
231
-static void rtnl_net_notifyid(struct net *net, int cmd, int id, gfp_t gfp);
240
+static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
241
+ struct nlmsghdr *nlh, gfp_t gfp);
232242 /* This function returns the id of a peer netns. If no id is assigned, one will
233243 * be allocated and returned.
234244 */
235245 int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
236246 {
237
- bool alloc = false, alive = false;
238247 int id;
239248
240249 if (refcount_read(&net->count) == 0)
241250 return NETNSA_NSID_NOT_ASSIGNED;
251
+
242252 spin_lock_bh(&net->nsid_lock);
243
- /*
244
- * When peer is obtained from RCU lists, we may race with
253
+ id = __peernet2id(net, peer);
254
+ if (id >= 0) {
255
+ spin_unlock_bh(&net->nsid_lock);
256
+ return id;
257
+ }
258
+
259
+ /* When peer is obtained from RCU lists, we may race with
245260 * its cleanup. Check whether it's alive, and this guarantees
246261 * we never hash a peer back to net->netns_ids, after it has
247262 * just been idr_remove()'d from there in cleanup_net().
248263 */
249
- if (maybe_get_net(peer))
250
- alive = alloc = true;
251
- id = __peernet2id_alloc(net, peer, &alloc);
264
+ if (!maybe_get_net(peer)) {
265
+ spin_unlock_bh(&net->nsid_lock);
266
+ return NETNSA_NSID_NOT_ASSIGNED;
267
+ }
268
+
269
+ id = alloc_netid(net, peer, -1);
252270 spin_unlock_bh(&net->nsid_lock);
253
- if (alloc && id >= 0)
254
- rtnl_net_notifyid(net, RTM_NEWNSID, id, gfp);
255
- if (alive)
256
- put_net(peer);
271
+
272
+ put_net(peer);
273
+ if (id < 0)
274
+ return NETNSA_NSID_NOT_ASSIGNED;
275
+
276
+ rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL, gfp);
277
+
257278 return id;
258279 }
259280 EXPORT_SYMBOL_GPL(peernet2id_alloc);
260281
261282 /* This function returns, if assigned, the id of a peer netns. */
262
-int peernet2id(struct net *net, struct net *peer)
283
+int peernet2id(const struct net *net, struct net *peer)
263284 {
264285 int id;
265286
....@@ -274,12 +295,12 @@
274295 /* This function returns true is the peer netns has an id assigned into the
275296 * current netns.
276297 */
277
-bool peernet_has_id(struct net *net, struct net *peer)
298
+bool peernet_has_id(const struct net *net, struct net *peer)
278299 {
279300 return peernet2id(net, peer) >= 0;
280301 }
281302
282
-struct net *get_net_ns_by_id(struct net *net, int id)
303
+struct net *get_net_ns_by_id(const struct net *net, int id)
283304 {
284305 struct net *peer;
285306
....@@ -308,6 +329,9 @@
308329 refcount_set(&net->count, 1);
309330 refcount_set(&net->passive, 1);
310331 get_random_bytes(&net->hash_mix, sizeof(u32));
332
+ preempt_disable();
333
+ atomic64_set(&net->net_cookie, gen_cookie_next(&net_cookie));
334
+ preempt_enable();
311335 net->dev_base_seq = 1;
312336 net->user_ns = user_ns;
313337 idr_init(&net->netns_ids);
....@@ -331,6 +355,12 @@
331355 */
332356 list_add(&net->exit_list, &net_exit_list);
333357 saved_ops = ops;
358
+ list_for_each_entry_continue_reverse(ops, &pernet_list, list)
359
+ ops_pre_exit_list(ops, &net_exit_list);
360
+
361
+ synchronize_rcu();
362
+
363
+ ops = saved_ops;
334364 list_for_each_entry_continue_reverse(ops, &pernet_list, list)
335365 ops_exit_list(ops, &net_exit_list);
336366
....@@ -389,10 +419,22 @@
389419 if (!net)
390420 goto out_free;
391421
422
+#ifdef CONFIG_KEYS
423
+ net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL);
424
+ if (!net->key_domain)
425
+ goto out_free_2;
426
+ refcount_set(&net->key_domain->usage, 1);
427
+#endif
428
+
392429 rcu_assign_pointer(net->gen, ng);
393430 out:
394431 return net;
395432
433
+#ifdef CONFIG_KEYS
434
+out_free_2:
435
+ kmem_cache_free(net_cachep, net);
436
+ net = NULL;
437
+#endif
396438 out_free:
397439 kfree(ng);
398440 goto out;
....@@ -444,6 +486,9 @@
444486
445487 if (rv < 0) {
446488 put_userns:
489
+#ifdef CONFIG_KEYS
490
+ key_remove_domain(net->key_domain);
491
+#endif
447492 put_user_ns(user_ns);
448493 net_drop_ns(net);
449494 dec_ucounts:
....@@ -498,7 +543,7 @@
498543 idr_remove(&tmp->netns_ids, id);
499544 spin_unlock_bh(&tmp->nsid_lock);
500545 if (id >= 0)
501
- rtnl_net_notifyid(tmp, RTM_DELNSID, id,
546
+ rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL,
502547 GFP_KERNEL);
503548 if (tmp == last)
504549 break;
....@@ -544,10 +589,15 @@
544589 list_add_tail(&net->exit_list, &net_exit_list);
545590 }
546591
592
+ /* Run all of the network namespace pre_exit methods */
593
+ list_for_each_entry_reverse(ops, &pernet_list, list)
594
+ ops_pre_exit_list(ops, &net_exit_list);
595
+
547596 /*
548597 * Another CPU might be rcu-iterating the list, wait for it.
549598 * This needs to be before calling the exit() notifiers, so
550599 * the rcu_barrier() below isn't sufficient alone.
600
+ * Also the pre_exit() and exit() methods need this barrier.
551601 */
552602 synchronize_rcu();
553603
....@@ -570,6 +620,9 @@
570620 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
571621 list_del_init(&net->exit_list);
572622 dec_net_namespaces(net->ucounts);
623
+#ifdef CONFIG_KEYS
624
+ key_remove_domain(net->key_domain);
625
+#endif
573626 put_user_ns(net->user_ns);
574627 net_drop_ns(net);
575628 }
....@@ -686,6 +739,7 @@
686739 [NETNSA_NSID] = { .type = NLA_S32 },
687740 [NETNSA_PID] = { .type = NLA_U32 },
688741 [NETNSA_FD] = { .type = NLA_U32 },
742
+ [NETNSA_TARGET_NSID] = { .type = NLA_S32 },
689743 };
690744
691745 static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
....@@ -697,8 +751,8 @@
697751 struct net *peer;
698752 int nsid, err;
699753
700
- err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
701
- rtnl_net_policy, extack);
754
+ err = nlmsg_parse_deprecated(nlh, sizeof(struct rtgenmsg), tb,
755
+ NETNSA_MAX, rtnl_net_policy, extack);
702756 if (err < 0)
703757 return err;
704758 if (!tb[NETNSA_NSID]) {
....@@ -736,7 +790,8 @@
736790 err = alloc_netid(net, peer, nsid);
737791 spin_unlock_bh(&net->nsid_lock);
738792 if (err >= 0) {
739
- rtnl_net_notifyid(net, RTM_NEWNSID, err, GFP_KERNEL);
793
+ rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid,
794
+ nlh, GFP_KERNEL);
740795 err = 0;
741796 } else if (err == -ENOSPC && nsid >= 0) {
742797 err = -EEXIST;
....@@ -752,23 +807,38 @@
752807 {
753808 return NLMSG_ALIGN(sizeof(struct rtgenmsg))
754809 + nla_total_size(sizeof(s32)) /* NETNSA_NSID */
810
+ + nla_total_size(sizeof(s32)) /* NETNSA_CURRENT_NSID */
755811 ;
756812 }
757813
758
-static int rtnl_net_fill(struct sk_buff *skb, u32 portid, u32 seq, int flags,
759
- int cmd, struct net *net, int nsid)
814
+struct net_fill_args {
815
+ u32 portid;
816
+ u32 seq;
817
+ int flags;
818
+ int cmd;
819
+ int nsid;
820
+ bool add_ref;
821
+ int ref_nsid;
822
+};
823
+
824
+static int rtnl_net_fill(struct sk_buff *skb, struct net_fill_args *args)
760825 {
761826 struct nlmsghdr *nlh;
762827 struct rtgenmsg *rth;
763828
764
- nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rth), flags);
829
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->cmd, sizeof(*rth),
830
+ args->flags);
765831 if (!nlh)
766832 return -EMSGSIZE;
767833
768834 rth = nlmsg_data(nlh);
769835 rth->rtgen_family = AF_UNSPEC;
770836
771
- if (nla_put_s32(skb, NETNSA_NSID, nsid))
837
+ if (nla_put_s32(skb, NETNSA_NSID, args->nsid))
838
+ goto nla_put_failure;
839
+
840
+ if (args->add_ref &&
841
+ nla_put_s32(skb, NETNSA_CURRENT_NSID, args->ref_nsid))
772842 goto nla_put_failure;
773843
774844 nlmsg_end(skb, nlh);
....@@ -779,18 +849,59 @@
779849 return -EMSGSIZE;
780850 }
781851
852
+static int rtnl_net_valid_getid_req(struct sk_buff *skb,
853
+ const struct nlmsghdr *nlh,
854
+ struct nlattr **tb,
855
+ struct netlink_ext_ack *extack)
856
+{
857
+ int i, err;
858
+
859
+ if (!netlink_strict_get_check(skb))
860
+ return nlmsg_parse_deprecated(nlh, sizeof(struct rtgenmsg),
861
+ tb, NETNSA_MAX, rtnl_net_policy,
862
+ extack);
863
+
864
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct rtgenmsg), tb,
865
+ NETNSA_MAX, rtnl_net_policy,
866
+ extack);
867
+ if (err)
868
+ return err;
869
+
870
+ for (i = 0; i <= NETNSA_MAX; i++) {
871
+ if (!tb[i])
872
+ continue;
873
+
874
+ switch (i) {
875
+ case NETNSA_PID:
876
+ case NETNSA_FD:
877
+ case NETNSA_NSID:
878
+ case NETNSA_TARGET_NSID:
879
+ break;
880
+ default:
881
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in peer netns getid request");
882
+ return -EINVAL;
883
+ }
884
+ }
885
+
886
+ return 0;
887
+}
888
+
782889 static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
783890 struct netlink_ext_ack *extack)
784891 {
785892 struct net *net = sock_net(skb->sk);
786893 struct nlattr *tb[NETNSA_MAX + 1];
894
+ struct net_fill_args fillargs = {
895
+ .portid = NETLINK_CB(skb).portid,
896
+ .seq = nlh->nlmsg_seq,
897
+ .cmd = RTM_NEWNSID,
898
+ };
899
+ struct net *peer, *target = net;
787900 struct nlattr *nla;
788901 struct sk_buff *msg;
789
- struct net *peer;
790
- int err, id;
902
+ int err;
791903
792
- err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
793
- rtnl_net_policy, extack);
904
+ err = rtnl_net_valid_getid_req(skb, nlh, tb, extack);
794905 if (err < 0)
795906 return err;
796907 if (tb[NETNSA_PID]) {
....@@ -799,6 +910,11 @@
799910 } else if (tb[NETNSA_FD]) {
800911 peer = get_net_ns_by_fd(nla_get_u32(tb[NETNSA_FD]));
801912 nla = tb[NETNSA_FD];
913
+ } else if (tb[NETNSA_NSID]) {
914
+ peer = get_net_ns_by_id(net, nla_get_s32(tb[NETNSA_NSID]));
915
+ if (!peer)
916
+ peer = ERR_PTR(-ENOENT);
917
+ nla = tb[NETNSA_NSID];
802918 } else {
803919 NL_SET_ERR_MSG(extack, "Peer netns reference is missing");
804920 return -EINVAL;
....@@ -810,15 +926,29 @@
810926 return PTR_ERR(peer);
811927 }
812928
929
+ if (tb[NETNSA_TARGET_NSID]) {
930
+ int id = nla_get_s32(tb[NETNSA_TARGET_NSID]);
931
+
932
+ target = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, id);
933
+ if (IS_ERR(target)) {
934
+ NL_SET_BAD_ATTR(extack, tb[NETNSA_TARGET_NSID]);
935
+ NL_SET_ERR_MSG(extack,
936
+ "Target netns reference is invalid");
937
+ err = PTR_ERR(target);
938
+ goto out;
939
+ }
940
+ fillargs.add_ref = true;
941
+ fillargs.ref_nsid = peernet2id(net, peer);
942
+ }
943
+
813944 msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL);
814945 if (!msg) {
815946 err = -ENOMEM;
816947 goto out;
817948 }
818949
819
- id = peernet2id(net, peer);
820
- err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
821
- RTM_NEWNSID, net, id);
950
+ fillargs.nsid = peernet2id(target, peer);
951
+ err = rtnl_net_fill(msg, &fillargs);
822952 if (err < 0)
823953 goto err_out;
824954
....@@ -828,14 +958,17 @@
828958 err_out:
829959 nlmsg_free(msg);
830960 out:
961
+ if (fillargs.add_ref)
962
+ put_net(target);
831963 put_net(peer);
832964 return err;
833965 }
834966
835967 struct rtnl_net_dump_cb {
836
- struct net *net;
968
+ struct net *tgt_net;
969
+ struct net *ref_net;
837970 struct sk_buff *skb;
838
- struct netlink_callback *cb;
971
+ struct net_fill_args fillargs;
839972 int idx;
840973 int s_idx;
841974 };
....@@ -849,9 +982,10 @@
849982 if (net_cb->idx < net_cb->s_idx)
850983 goto cont;
851984
852
- ret = rtnl_net_fill(net_cb->skb, NETLINK_CB(net_cb->cb->skb).portid,
853
- net_cb->cb->nlh->nlmsg_seq, NLM_F_MULTI,
854
- RTM_NEWNSID, net_cb->net, id);
985
+ net_cb->fillargs.nsid = id;
986
+ if (net_cb->fillargs.add_ref)
987
+ net_cb->fillargs.ref_nsid = __peernet2id(net_cb->ref_net, peer);
988
+ ret = rtnl_net_fill(net_cb->skb, &net_cb->fillargs);
855989 if (ret < 0)
856990 return ret;
857991
....@@ -860,27 +994,90 @@
860994 return 0;
861995 }
862996
997
+static int rtnl_valid_dump_net_req(const struct nlmsghdr *nlh, struct sock *sk,
998
+ struct rtnl_net_dump_cb *net_cb,
999
+ struct netlink_callback *cb)
1000
+{
1001
+ struct netlink_ext_ack *extack = cb->extack;
1002
+ struct nlattr *tb[NETNSA_MAX + 1];
1003
+ int err, i;
1004
+
1005
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct rtgenmsg), tb,
1006
+ NETNSA_MAX, rtnl_net_policy,
1007
+ extack);
1008
+ if (err < 0)
1009
+ return err;
1010
+
1011
+ for (i = 0; i <= NETNSA_MAX; i++) {
1012
+ if (!tb[i])
1013
+ continue;
1014
+
1015
+ if (i == NETNSA_TARGET_NSID) {
1016
+ struct net *net;
1017
+
1018
+ net = rtnl_get_net_ns_capable(sk, nla_get_s32(tb[i]));
1019
+ if (IS_ERR(net)) {
1020
+ NL_SET_BAD_ATTR(extack, tb[i]);
1021
+ NL_SET_ERR_MSG(extack,
1022
+ "Invalid target network namespace id");
1023
+ return PTR_ERR(net);
1024
+ }
1025
+ net_cb->fillargs.add_ref = true;
1026
+ net_cb->ref_net = net_cb->tgt_net;
1027
+ net_cb->tgt_net = net;
1028
+ } else {
1029
+ NL_SET_BAD_ATTR(extack, tb[i]);
1030
+ NL_SET_ERR_MSG(extack,
1031
+ "Unsupported attribute in dump request");
1032
+ return -EINVAL;
1033
+ }
1034
+ }
1035
+
1036
+ return 0;
1037
+}
1038
+
8631039 static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
8641040 {
865
- struct net *net = sock_net(skb->sk);
8661041 struct rtnl_net_dump_cb net_cb = {
867
- .net = net,
1042
+ .tgt_net = sock_net(skb->sk),
8681043 .skb = skb,
869
- .cb = cb,
1044
+ .fillargs = {
1045
+ .portid = NETLINK_CB(cb->skb).portid,
1046
+ .seq = cb->nlh->nlmsg_seq,
1047
+ .flags = NLM_F_MULTI,
1048
+ .cmd = RTM_NEWNSID,
1049
+ },
8701050 .idx = 0,
8711051 .s_idx = cb->args[0],
8721052 };
1053
+ int err = 0;
1054
+
1055
+ if (cb->strict_check) {
1056
+ err = rtnl_valid_dump_net_req(cb->nlh, skb->sk, &net_cb, cb);
1057
+ if (err < 0)
1058
+ goto end;
1059
+ }
8731060
8741061 rcu_read_lock();
875
- idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb);
1062
+ idr_for_each(&net_cb.tgt_net->netns_ids, rtnl_net_dumpid_one, &net_cb);
8761063 rcu_read_unlock();
8771064
8781065 cb->args[0] = net_cb.idx;
879
- return skb->len;
1066
+end:
1067
+ if (net_cb.fillargs.add_ref)
1068
+ put_net(net_cb.tgt_net);
1069
+ return err < 0 ? err : skb->len;
8801070 }
8811071
882
-static void rtnl_net_notifyid(struct net *net, int cmd, int id, gfp_t gfp)
1072
+static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
1073
+ struct nlmsghdr *nlh, gfp_t gfp)
8831074 {
1075
+ struct net_fill_args fillargs = {
1076
+ .portid = portid,
1077
+ .seq = nlh ? nlh->nlmsg_seq : 0,
1078
+ .cmd = cmd,
1079
+ .nsid = id,
1080
+ };
8841081 struct sk_buff *msg;
8851082 int err = -ENOMEM;
8861083
....@@ -888,11 +1085,11 @@
8881085 if (!msg)
8891086 goto out;
8901087
891
- err = rtnl_net_fill(msg, 0, 0, 0, cmd, net, id);
1088
+ err = rtnl_net_fill(msg, &fillargs);
8921089 if (err < 0)
8931090 goto err_out;
8941091
895
- rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, gfp);
1092
+ rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, gfp);
8961093 return;
8971094
8981095 err_out:
....@@ -967,6 +1164,8 @@
9671164 out_undo:
9681165 /* If I have an error cleanup all namespaces I initialized */
9691166 list_del(&ops->list);
1167
+ ops_pre_exit_list(ops, &net_exit_list);
1168
+ synchronize_rcu();
9701169 ops_exit_list(ops, &net_exit_list);
9711170 ops_free_list(ops, &net_exit_list);
9721171 return error;
....@@ -981,6 +1180,8 @@
9811180 /* See comment in __register_pernet_operations() */
9821181 for_each_net(net)
9831182 list_add_tail(&net->exit_list, &net_exit_list);
1183
+ ops_pre_exit_list(ops, &net_exit_list);
1184
+ synchronize_rcu();
9841185 ops_exit_list(ops, &net_exit_list);
9851186 ops_free_list(ops, &net_exit_list);
9861187 }
....@@ -1005,6 +1206,8 @@
10051206 } else {
10061207 LIST_HEAD(net_exit_list);
10071208 list_add(&init_net.exit_list, &net_exit_list);
1209
+ ops_pre_exit_list(ops, &net_exit_list);
1210
+ synchronize_rcu();
10081211 ops_exit_list(ops, &net_exit_list);
10091212 ops_free_list(ops, &net_exit_list);
10101213 }
....@@ -1166,12 +1369,13 @@
11661369 put_net(to_net_ns(ns));
11671370 }
11681371
1169
-static int netns_install(struct nsproxy *nsproxy, struct ns_common *ns)
1372
+static int netns_install(struct nsset *nsset, struct ns_common *ns)
11701373 {
1374
+ struct nsproxy *nsproxy = nsset->nsproxy;
11711375 struct net *net = to_net_ns(ns);
11721376
11731377 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
1174
- !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
1378
+ !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
11751379 return -EPERM;
11761380
11771381 put_net(nsproxy->net_ns);