Commit 444f378b237a0f728f5c4aba752c08d13c209344

Authored by Linus Torvalds
1 parent 8c8c4bafc3

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
... ... @@ -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;
... ... @@ -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)
... ... @@ -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)