Commit 444f378b237a0f728f5c4aba752c08d13c209344
1 parent
8c8c4bafc3
Exists in
master
and in
4 other branches
Revert "[PATCH] namespaces: fix exit race by splitting exit"
This reverts commit 7a238fcba0629b6f2edbcd37458bae56fcf36be5 in preparation for a better and simpler fix proposed by Eric Biederman (and fixed up by Serge Hallyn) Acked-by: Serge E. Hallyn <serue@us.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 4 changed files with 16 additions and 40 deletions Side-by-side Diff
include/linux/nsproxy.h
... | ... | @@ -35,31 +35,23 @@ |
35 | 35 | int copy_namespaces(int flags, struct task_struct *tsk); |
36 | 36 | void get_task_namespaces(struct task_struct *tsk); |
37 | 37 | void free_nsproxy(struct nsproxy *ns); |
38 | -struct nsproxy *put_nsproxy(struct nsproxy *ns); | |
39 | 38 | |
40 | -static inline void finalize_put_nsproxy(struct nsproxy *ns) | |
39 | +static inline void put_nsproxy(struct nsproxy *ns) | |
41 | 40 | { |
42 | - if (ns) | |
41 | + if (atomic_dec_and_test(&ns->count)) { | |
43 | 42 | free_nsproxy(ns); |
43 | + } | |
44 | 44 | } |
45 | 45 | |
46 | -static inline void put_and_finalize_nsproxy(struct nsproxy *ns) | |
46 | +static inline void exit_task_namespaces(struct task_struct *p) | |
47 | 47 | { |
48 | - finalize_put_nsproxy(put_nsproxy(ns)); | |
49 | -} | |
50 | - | |
51 | -static inline struct nsproxy *preexit_task_namespaces(struct task_struct *p) | |
52 | -{ | |
53 | - return put_nsproxy(p->nsproxy); | |
54 | -} | |
55 | - | |
56 | -static inline void exit_task_namespaces(struct task_struct *p, | |
57 | - struct nsproxy *ns) | |
58 | -{ | |
59 | - task_lock(p); | |
60 | - p->nsproxy = NULL; | |
61 | - task_unlock(p); | |
62 | - finalize_put_nsproxy(ns); | |
48 | + struct nsproxy *ns = p->nsproxy; | |
49 | + if (ns) { | |
50 | + task_lock(p); | |
51 | + p->nsproxy = NULL; | |
52 | + task_unlock(p); | |
53 | + put_nsproxy(ns); | |
54 | + } | |
63 | 55 | } |
64 | 56 | #endif |
kernel/exit.c
... | ... | @@ -396,7 +396,7 @@ |
396 | 396 | current->fs = fs; |
397 | 397 | atomic_inc(&fs->count); |
398 | 398 | |
399 | - put_and_finalize_nsproxy(current->nsproxy); | |
399 | + exit_task_namespaces(current); | |
400 | 400 | current->nsproxy = init_task.nsproxy; |
401 | 401 | get_task_namespaces(current); |
402 | 402 | |
... | ... | @@ -853,7 +853,6 @@ |
853 | 853 | fastcall NORET_TYPE void do_exit(long code) |
854 | 854 | { |
855 | 855 | struct task_struct *tsk = current; |
856 | - struct nsproxy *ns; | |
857 | 856 | int group_dead; |
858 | 857 | |
859 | 858 | profile_task_exit(tsk); |
860 | 859 | |
... | ... | @@ -939,9 +938,8 @@ |
939 | 938 | |
940 | 939 | tsk->exit_code = code; |
941 | 940 | proc_exit_connector(tsk); |
942 | - ns = preexit_task_namespaces(tsk); | |
943 | 941 | exit_notify(tsk); |
944 | - exit_task_namespaces(tsk, ns); | |
942 | + exit_task_namespaces(tsk); | |
945 | 943 | #ifdef CONFIG_NUMA |
946 | 944 | mpol_free(tsk->mempolicy); |
947 | 945 | tsk->mempolicy = NULL; |
kernel/fork.c
... | ... | @@ -1265,7 +1265,7 @@ |
1265 | 1265 | return p; |
1266 | 1266 | |
1267 | 1267 | bad_fork_cleanup_namespaces: |
1268 | - put_and_finalize_nsproxy(p->nsproxy); | |
1268 | + exit_task_namespaces(p); | |
1269 | 1269 | bad_fork_cleanup_keys: |
1270 | 1270 | exit_keys(p); |
1271 | 1271 | bad_fork_cleanup_mm: |
... | ... | @@ -1711,7 +1711,7 @@ |
1711 | 1711 | } |
1712 | 1712 | |
1713 | 1713 | if (new_nsproxy) |
1714 | - put_and_finalize_nsproxy(new_nsproxy); | |
1714 | + put_nsproxy(new_nsproxy); | |
1715 | 1715 | |
1716 | 1716 | bad_unshare_cleanup_ipc: |
1717 | 1717 | if (new_ipc) |
kernel/nsproxy.c
... | ... | @@ -117,7 +117,7 @@ |
117 | 117 | goto out_pid; |
118 | 118 | |
119 | 119 | out: |
120 | - put_and_finalize_nsproxy(old_ns); | |
120 | + put_nsproxy(old_ns); | |
121 | 121 | return err; |
122 | 122 | |
123 | 123 | out_pid: |
... | ... | @@ -133,20 +133,6 @@ |
133 | 133 | tsk->nsproxy = old_ns; |
134 | 134 | kfree(new_ns); |
135 | 135 | goto out; |
136 | -} | |
137 | - | |
138 | -struct nsproxy *put_nsproxy(struct nsproxy *ns) | |
139 | -{ | |
140 | - if (ns) { | |
141 | - if (atomic_dec_and_test(&ns->count)) { | |
142 | - if (ns->mnt_ns) { | |
143 | - put_mnt_ns(ns->mnt_ns); | |
144 | - ns->mnt_ns = NULL; | |
145 | - } | |
146 | - return ns; | |
147 | - } | |
148 | - } | |
149 | - return NULL; | |
150 | 136 | } |
151 | 137 | |
152 | 138 | void free_nsproxy(struct nsproxy *ns) |