forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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,20 @@
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);
74
+
75
+u64 __net_gen_cookie(struct net *net)
76
+{
77
+ while (1) {
78
+ u64 res = atomic64_read(&net->net_cookie);
79
+
80
+ if (res)
81
+ return res;
82
+ res = gen_cookie_next(&net_cookie);
83
+ atomic64_cmpxchg(&net->net_cookie, 0, res);
84
+ }
85
+}
6386
6487 static struct net_generic *net_alloc_generic(void)
6588 {
....@@ -112,6 +135,7 @@
112135
113136 static int ops_init(const struct pernet_operations *ops, struct net *net)
114137 {
138
+ struct net_generic *ng;
115139 int err = -ENOMEM;
116140 void *data = NULL;
117141
....@@ -130,7 +154,13 @@
130154 if (!err)
131155 return 0;
132156
157
+ if (ops->id && ops->size) {
133158 cleanup:
159
+ ng = rcu_dereference_protected(net->gen,
160
+ lockdep_is_held(&pernet_ops_rwsem));
161
+ ng->ptr[*ops->id] = NULL;
162
+ }
163
+
134164 kfree(data);
135165
136166 out:
....@@ -141,6 +171,17 @@
141171 {
142172 if (ops->id && ops->size) {
143173 kfree(net_generic(net, *ops->id));
174
+ }
175
+}
176
+
177
+static void ops_pre_exit_list(const struct pernet_operations *ops,
178
+ struct list_head *net_exit_list)
179
+{
180
+ struct net *net;
181
+
182
+ if (ops->pre_exit) {
183
+ list_for_each_entry(net, net_exit_list, exit_list)
184
+ ops->pre_exit(net);
144185 }
145186 }
146187
....@@ -194,16 +235,10 @@
194235 return 0;
195236 }
196237
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)
238
+/* Must be called from RCU-critical section or with nsid_lock held */
239
+static int __peernet2id(const struct net *net, struct net *peer)
202240 {
203241 int id = idr_for_each(&net->netns_ids, net_eq_idr, peer);
204
- bool alloc_it = *alloc;
205
-
206
- *alloc = false;
207242
208243 /* Magic value for id 0. */
209244 if (id == NET_ID_ZERO)
....@@ -211,55 +246,53 @@
211246 if (id > 0)
212247 return id;
213248
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
-
220249 return NETNSA_NSID_NOT_ASSIGNED;
221250 }
222251
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);
252
+static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
253
+ struct nlmsghdr *nlh, gfp_t gfp);
232254 /* This function returns the id of a peer netns. If no id is assigned, one will
233255 * be allocated and returned.
234256 */
235257 int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
236258 {
237
- bool alloc = false, alive = false;
238259 int id;
239260
240261 if (refcount_read(&net->count) == 0)
241262 return NETNSA_NSID_NOT_ASSIGNED;
263
+
242264 spin_lock_bh(&net->nsid_lock);
243
- /*
244
- * When peer is obtained from RCU lists, we may race with
265
+ id = __peernet2id(net, peer);
266
+ if (id >= 0) {
267
+ spin_unlock_bh(&net->nsid_lock);
268
+ return id;
269
+ }
270
+
271
+ /* When peer is obtained from RCU lists, we may race with
245272 * its cleanup. Check whether it's alive, and this guarantees
246273 * we never hash a peer back to net->netns_ids, after it has
247274 * just been idr_remove()'d from there in cleanup_net().
248275 */
249
- if (maybe_get_net(peer))
250
- alive = alloc = true;
251
- id = __peernet2id_alloc(net, peer, &alloc);
276
+ if (!maybe_get_net(peer)) {
277
+ spin_unlock_bh(&net->nsid_lock);
278
+ return NETNSA_NSID_NOT_ASSIGNED;
279
+ }
280
+
281
+ id = alloc_netid(net, peer, -1);
252282 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);
283
+
284
+ put_net(peer);
285
+ if (id < 0)
286
+ return NETNSA_NSID_NOT_ASSIGNED;
287
+
288
+ rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL, gfp);
289
+
257290 return id;
258291 }
259292 EXPORT_SYMBOL_GPL(peernet2id_alloc);
260293
261294 /* This function returns, if assigned, the id of a peer netns. */
262
-int peernet2id(struct net *net, struct net *peer)
295
+int peernet2id(const struct net *net, struct net *peer)
263296 {
264297 int id;
265298
....@@ -274,12 +307,12 @@
274307 /* This function returns true is the peer netns has an id assigned into the
275308 * current netns.
276309 */
277
-bool peernet_has_id(struct net *net, struct net *peer)
310
+bool peernet_has_id(const struct net *net, struct net *peer)
278311 {
279312 return peernet2id(net, peer) >= 0;
280313 }
281314
282
-struct net *get_net_ns_by_id(struct net *net, int id)
315
+struct net *get_net_ns_by_id(const struct net *net, int id)
283316 {
284317 struct net *peer;
285318
....@@ -331,6 +364,12 @@
331364 */
332365 list_add(&net->exit_list, &net_exit_list);
333366 saved_ops = ops;
367
+ list_for_each_entry_continue_reverse(ops, &pernet_list, list)
368
+ ops_pre_exit_list(ops, &net_exit_list);
369
+
370
+ synchronize_rcu();
371
+
372
+ ops = saved_ops;
334373 list_for_each_entry_continue_reverse(ops, &pernet_list, list)
335374 ops_exit_list(ops, &net_exit_list);
336375
....@@ -389,10 +428,22 @@
389428 if (!net)
390429 goto out_free;
391430
431
+#ifdef CONFIG_KEYS
432
+ net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL);
433
+ if (!net->key_domain)
434
+ goto out_free_2;
435
+ refcount_set(&net->key_domain->usage, 1);
436
+#endif
437
+
392438 rcu_assign_pointer(net->gen, ng);
393439 out:
394440 return net;
395441
442
+#ifdef CONFIG_KEYS
443
+out_free_2:
444
+ kmem_cache_free(net_cachep, net);
445
+ net = NULL;
446
+#endif
396447 out_free:
397448 kfree(ng);
398449 goto out;
....@@ -444,6 +495,9 @@
444495
445496 if (rv < 0) {
446497 put_userns:
498
+#ifdef CONFIG_KEYS
499
+ key_remove_domain(net->key_domain);
500
+#endif
447501 put_user_ns(user_ns);
448502 net_drop_ns(net);
449503 dec_ucounts:
....@@ -498,7 +552,7 @@
498552 idr_remove(&tmp->netns_ids, id);
499553 spin_unlock_bh(&tmp->nsid_lock);
500554 if (id >= 0)
501
- rtnl_net_notifyid(tmp, RTM_DELNSID, id,
555
+ rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL,
502556 GFP_KERNEL);
503557 if (tmp == last)
504558 break;
....@@ -544,10 +598,15 @@
544598 list_add_tail(&net->exit_list, &net_exit_list);
545599 }
546600
601
+ /* Run all of the network namespace pre_exit methods */
602
+ list_for_each_entry_reverse(ops, &pernet_list, list)
603
+ ops_pre_exit_list(ops, &net_exit_list);
604
+
547605 /*
548606 * Another CPU might be rcu-iterating the list, wait for it.
549607 * This needs to be before calling the exit() notifiers, so
550608 * the rcu_barrier() below isn't sufficient alone.
609
+ * Also the pre_exit() and exit() methods need this barrier.
551610 */
552611 synchronize_rcu();
553612
....@@ -570,6 +629,9 @@
570629 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
571630 list_del_init(&net->exit_list);
572631 dec_net_namespaces(net->ucounts);
632
+#ifdef CONFIG_KEYS
633
+ key_remove_domain(net->key_domain);
634
+#endif
573635 put_user_ns(net->user_ns);
574636 net_drop_ns(net);
575637 }
....@@ -686,6 +748,7 @@
686748 [NETNSA_NSID] = { .type = NLA_S32 },
687749 [NETNSA_PID] = { .type = NLA_U32 },
688750 [NETNSA_FD] = { .type = NLA_U32 },
751
+ [NETNSA_TARGET_NSID] = { .type = NLA_S32 },
689752 };
690753
691754 static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
....@@ -697,8 +760,8 @@
697760 struct net *peer;
698761 int nsid, err;
699762
700
- err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
701
- rtnl_net_policy, extack);
763
+ err = nlmsg_parse_deprecated(nlh, sizeof(struct rtgenmsg), tb,
764
+ NETNSA_MAX, rtnl_net_policy, extack);
702765 if (err < 0)
703766 return err;
704767 if (!tb[NETNSA_NSID]) {
....@@ -736,7 +799,8 @@
736799 err = alloc_netid(net, peer, nsid);
737800 spin_unlock_bh(&net->nsid_lock);
738801 if (err >= 0) {
739
- rtnl_net_notifyid(net, RTM_NEWNSID, err, GFP_KERNEL);
802
+ rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid,
803
+ nlh, GFP_KERNEL);
740804 err = 0;
741805 } else if (err == -ENOSPC && nsid >= 0) {
742806 err = -EEXIST;
....@@ -752,23 +816,38 @@
752816 {
753817 return NLMSG_ALIGN(sizeof(struct rtgenmsg))
754818 + nla_total_size(sizeof(s32)) /* NETNSA_NSID */
819
+ + nla_total_size(sizeof(s32)) /* NETNSA_CURRENT_NSID */
755820 ;
756821 }
757822
758
-static int rtnl_net_fill(struct sk_buff *skb, u32 portid, u32 seq, int flags,
759
- int cmd, struct net *net, int nsid)
823
+struct net_fill_args {
824
+ u32 portid;
825
+ u32 seq;
826
+ int flags;
827
+ int cmd;
828
+ int nsid;
829
+ bool add_ref;
830
+ int ref_nsid;
831
+};
832
+
833
+static int rtnl_net_fill(struct sk_buff *skb, struct net_fill_args *args)
760834 {
761835 struct nlmsghdr *nlh;
762836 struct rtgenmsg *rth;
763837
764
- nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rth), flags);
838
+ nlh = nlmsg_put(skb, args->portid, args->seq, args->cmd, sizeof(*rth),
839
+ args->flags);
765840 if (!nlh)
766841 return -EMSGSIZE;
767842
768843 rth = nlmsg_data(nlh);
769844 rth->rtgen_family = AF_UNSPEC;
770845
771
- if (nla_put_s32(skb, NETNSA_NSID, nsid))
846
+ if (nla_put_s32(skb, NETNSA_NSID, args->nsid))
847
+ goto nla_put_failure;
848
+
849
+ if (args->add_ref &&
850
+ nla_put_s32(skb, NETNSA_CURRENT_NSID, args->ref_nsid))
772851 goto nla_put_failure;
773852
774853 nlmsg_end(skb, nlh);
....@@ -779,18 +858,59 @@
779858 return -EMSGSIZE;
780859 }
781860
861
+static int rtnl_net_valid_getid_req(struct sk_buff *skb,
862
+ const struct nlmsghdr *nlh,
863
+ struct nlattr **tb,
864
+ struct netlink_ext_ack *extack)
865
+{
866
+ int i, err;
867
+
868
+ if (!netlink_strict_get_check(skb))
869
+ return nlmsg_parse_deprecated(nlh, sizeof(struct rtgenmsg),
870
+ tb, NETNSA_MAX, rtnl_net_policy,
871
+ extack);
872
+
873
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct rtgenmsg), tb,
874
+ NETNSA_MAX, rtnl_net_policy,
875
+ extack);
876
+ if (err)
877
+ return err;
878
+
879
+ for (i = 0; i <= NETNSA_MAX; i++) {
880
+ if (!tb[i])
881
+ continue;
882
+
883
+ switch (i) {
884
+ case NETNSA_PID:
885
+ case NETNSA_FD:
886
+ case NETNSA_NSID:
887
+ case NETNSA_TARGET_NSID:
888
+ break;
889
+ default:
890
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in peer netns getid request");
891
+ return -EINVAL;
892
+ }
893
+ }
894
+
895
+ return 0;
896
+}
897
+
782898 static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
783899 struct netlink_ext_ack *extack)
784900 {
785901 struct net *net = sock_net(skb->sk);
786902 struct nlattr *tb[NETNSA_MAX + 1];
903
+ struct net_fill_args fillargs = {
904
+ .portid = NETLINK_CB(skb).portid,
905
+ .seq = nlh->nlmsg_seq,
906
+ .cmd = RTM_NEWNSID,
907
+ };
908
+ struct net *peer, *target = net;
787909 struct nlattr *nla;
788910 struct sk_buff *msg;
789
- struct net *peer;
790
- int err, id;
911
+ int err;
791912
792
- err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
793
- rtnl_net_policy, extack);
913
+ err = rtnl_net_valid_getid_req(skb, nlh, tb, extack);
794914 if (err < 0)
795915 return err;
796916 if (tb[NETNSA_PID]) {
....@@ -799,6 +919,11 @@
799919 } else if (tb[NETNSA_FD]) {
800920 peer = get_net_ns_by_fd(nla_get_u32(tb[NETNSA_FD]));
801921 nla = tb[NETNSA_FD];
922
+ } else if (tb[NETNSA_NSID]) {
923
+ peer = get_net_ns_by_id(net, nla_get_s32(tb[NETNSA_NSID]));
924
+ if (!peer)
925
+ peer = ERR_PTR(-ENOENT);
926
+ nla = tb[NETNSA_NSID];
802927 } else {
803928 NL_SET_ERR_MSG(extack, "Peer netns reference is missing");
804929 return -EINVAL;
....@@ -810,15 +935,29 @@
810935 return PTR_ERR(peer);
811936 }
812937
938
+ if (tb[NETNSA_TARGET_NSID]) {
939
+ int id = nla_get_s32(tb[NETNSA_TARGET_NSID]);
940
+
941
+ target = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, id);
942
+ if (IS_ERR(target)) {
943
+ NL_SET_BAD_ATTR(extack, tb[NETNSA_TARGET_NSID]);
944
+ NL_SET_ERR_MSG(extack,
945
+ "Target netns reference is invalid");
946
+ err = PTR_ERR(target);
947
+ goto out;
948
+ }
949
+ fillargs.add_ref = true;
950
+ fillargs.ref_nsid = peernet2id(net, peer);
951
+ }
952
+
813953 msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL);
814954 if (!msg) {
815955 err = -ENOMEM;
816956 goto out;
817957 }
818958
819
- id = peernet2id(net, peer);
820
- err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
821
- RTM_NEWNSID, net, id);
959
+ fillargs.nsid = peernet2id(target, peer);
960
+ err = rtnl_net_fill(msg, &fillargs);
822961 if (err < 0)
823962 goto err_out;
824963
....@@ -828,14 +967,17 @@
828967 err_out:
829968 nlmsg_free(msg);
830969 out:
970
+ if (fillargs.add_ref)
971
+ put_net(target);
831972 put_net(peer);
832973 return err;
833974 }
834975
835976 struct rtnl_net_dump_cb {
836
- struct net *net;
977
+ struct net *tgt_net;
978
+ struct net *ref_net;
837979 struct sk_buff *skb;
838
- struct netlink_callback *cb;
980
+ struct net_fill_args fillargs;
839981 int idx;
840982 int s_idx;
841983 };
....@@ -849,9 +991,10 @@
849991 if (net_cb->idx < net_cb->s_idx)
850992 goto cont;
851993
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);
994
+ net_cb->fillargs.nsid = id;
995
+ if (net_cb->fillargs.add_ref)
996
+ net_cb->fillargs.ref_nsid = __peernet2id(net_cb->ref_net, peer);
997
+ ret = rtnl_net_fill(net_cb->skb, &net_cb->fillargs);
855998 if (ret < 0)
856999 return ret;
8571000
....@@ -860,27 +1003,90 @@
8601003 return 0;
8611004 }
8621005
1006
+static int rtnl_valid_dump_net_req(const struct nlmsghdr *nlh, struct sock *sk,
1007
+ struct rtnl_net_dump_cb *net_cb,
1008
+ struct netlink_callback *cb)
1009
+{
1010
+ struct netlink_ext_ack *extack = cb->extack;
1011
+ struct nlattr *tb[NETNSA_MAX + 1];
1012
+ int err, i;
1013
+
1014
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct rtgenmsg), tb,
1015
+ NETNSA_MAX, rtnl_net_policy,
1016
+ extack);
1017
+ if (err < 0)
1018
+ return err;
1019
+
1020
+ for (i = 0; i <= NETNSA_MAX; i++) {
1021
+ if (!tb[i])
1022
+ continue;
1023
+
1024
+ if (i == NETNSA_TARGET_NSID) {
1025
+ struct net *net;
1026
+
1027
+ net = rtnl_get_net_ns_capable(sk, nla_get_s32(tb[i]));
1028
+ if (IS_ERR(net)) {
1029
+ NL_SET_BAD_ATTR(extack, tb[i]);
1030
+ NL_SET_ERR_MSG(extack,
1031
+ "Invalid target network namespace id");
1032
+ return PTR_ERR(net);
1033
+ }
1034
+ net_cb->fillargs.add_ref = true;
1035
+ net_cb->ref_net = net_cb->tgt_net;
1036
+ net_cb->tgt_net = net;
1037
+ } else {
1038
+ NL_SET_BAD_ATTR(extack, tb[i]);
1039
+ NL_SET_ERR_MSG(extack,
1040
+ "Unsupported attribute in dump request");
1041
+ return -EINVAL;
1042
+ }
1043
+ }
1044
+
1045
+ return 0;
1046
+}
1047
+
8631048 static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
8641049 {
865
- struct net *net = sock_net(skb->sk);
8661050 struct rtnl_net_dump_cb net_cb = {
867
- .net = net,
1051
+ .tgt_net = sock_net(skb->sk),
8681052 .skb = skb,
869
- .cb = cb,
1053
+ .fillargs = {
1054
+ .portid = NETLINK_CB(cb->skb).portid,
1055
+ .seq = cb->nlh->nlmsg_seq,
1056
+ .flags = NLM_F_MULTI,
1057
+ .cmd = RTM_NEWNSID,
1058
+ },
8701059 .idx = 0,
8711060 .s_idx = cb->args[0],
8721061 };
1062
+ int err = 0;
1063
+
1064
+ if (cb->strict_check) {
1065
+ err = rtnl_valid_dump_net_req(cb->nlh, skb->sk, &net_cb, cb);
1066
+ if (err < 0)
1067
+ goto end;
1068
+ }
8731069
8741070 rcu_read_lock();
875
- idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb);
1071
+ idr_for_each(&net_cb.tgt_net->netns_ids, rtnl_net_dumpid_one, &net_cb);
8761072 rcu_read_unlock();
8771073
8781074 cb->args[0] = net_cb.idx;
879
- return skb->len;
1075
+end:
1076
+ if (net_cb.fillargs.add_ref)
1077
+ put_net(net_cb.tgt_net);
1078
+ return err < 0 ? err : skb->len;
8801079 }
8811080
882
-static void rtnl_net_notifyid(struct net *net, int cmd, int id, gfp_t gfp)
1081
+static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
1082
+ struct nlmsghdr *nlh, gfp_t gfp)
8831083 {
1084
+ struct net_fill_args fillargs = {
1085
+ .portid = portid,
1086
+ .seq = nlh ? nlh->nlmsg_seq : 0,
1087
+ .cmd = cmd,
1088
+ .nsid = id,
1089
+ };
8841090 struct sk_buff *msg;
8851091 int err = -ENOMEM;
8861092
....@@ -888,11 +1094,11 @@
8881094 if (!msg)
8891095 goto out;
8901096
891
- err = rtnl_net_fill(msg, 0, 0, 0, cmd, net, id);
1097
+ err = rtnl_net_fill(msg, &fillargs);
8921098 if (err < 0)
8931099 goto err_out;
8941100
895
- rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, gfp);
1101
+ rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, gfp);
8961102 return;
8971103
8981104 err_out:
....@@ -921,6 +1127,10 @@
9211127 panic("Could not allocate generic netns");
9221128
9231129 rcu_assign_pointer(init_net.gen, ng);
1130
+
1131
+ preempt_disable();
1132
+ __net_gen_cookie(&init_net);
1133
+ preempt_enable();
9241134
9251135 down_write(&pernet_ops_rwsem);
9261136 if (setup_net(&init_net, &init_user_ns))
....@@ -967,6 +1177,8 @@
9671177 out_undo:
9681178 /* If I have an error cleanup all namespaces I initialized */
9691179 list_del(&ops->list);
1180
+ ops_pre_exit_list(ops, &net_exit_list);
1181
+ synchronize_rcu();
9701182 ops_exit_list(ops, &net_exit_list);
9711183 ops_free_list(ops, &net_exit_list);
9721184 return error;
....@@ -981,6 +1193,8 @@
9811193 /* See comment in __register_pernet_operations() */
9821194 for_each_net(net)
9831195 list_add_tail(&net->exit_list, &net_exit_list);
1196
+ ops_pre_exit_list(ops, &net_exit_list);
1197
+ synchronize_rcu();
9841198 ops_exit_list(ops, &net_exit_list);
9851199 ops_free_list(ops, &net_exit_list);
9861200 }
....@@ -1005,6 +1219,8 @@
10051219 } else {
10061220 LIST_HEAD(net_exit_list);
10071221 list_add(&init_net.exit_list, &net_exit_list);
1222
+ ops_pre_exit_list(ops, &net_exit_list);
1223
+ synchronize_rcu();
10081224 ops_exit_list(ops, &net_exit_list);
10091225 ops_free_list(ops, &net_exit_list);
10101226 }
....@@ -1166,12 +1382,13 @@
11661382 put_net(to_net_ns(ns));
11671383 }
11681384
1169
-static int netns_install(struct nsproxy *nsproxy, struct ns_common *ns)
1385
+static int netns_install(struct nsset *nsset, struct ns_common *ns)
11701386 {
1387
+ struct nsproxy *nsproxy = nsset->nsproxy;
11711388 struct net *net = to_net_ns(ns);
11721389
11731390 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
1174
- !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
1391
+ !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
11751392 return -EPERM;
11761393
11771394 put_net(nsproxy->net_ns);