diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-30 16:35:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-30 16:35:18 -0500 |
commit | 444f378b237a0f728f5c4aba752c08d13c209344 (patch) | |
tree | 248fd00bb2e60cb0890fce38b6a66fed65f977e4 | |
parent | 8c8c4bafc3a20a6fb9078315ff865bc42276f9ba (diff) |
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>
-rw-r--r-- | include/linux/nsproxy.h | 30 | ||||
-rw-r--r-- | kernel/exit.c | 6 | ||||
-rw-r--r-- | kernel/fork.c | 4 | ||||
-rw-r--r-- | kernel/nsproxy.c | 16 |
4 files changed, 16 insertions, 40 deletions
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index 678e1d38effb..0b9f0dc30d61 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h | |||
@@ -35,30 +35,22 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig); | |||
35 | int copy_namespaces(int flags, struct task_struct *tsk); | 35 | int copy_namespaces(int flags, struct task_struct *tsk); |
36 | void get_task_namespaces(struct task_struct *tsk); | 36 | void get_task_namespaces(struct task_struct *tsk); |
37 | void free_nsproxy(struct nsproxy *ns); | 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 | free_nsproxy(ns); | 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)); | 48 | struct nsproxy *ns = p->nsproxy; |
49 | } | 49 | if (ns) { |
50 | 50 | task_lock(p); | |
51 | static inline struct nsproxy *preexit_task_namespaces(struct task_struct *p) | 51 | p->nsproxy = NULL; |
52 | { | 52 | task_unlock(p); |
53 | return put_nsproxy(p->nsproxy); | 53 | put_nsproxy(ns); |
54 | } | 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); | ||
63 | } | 55 | } |
64 | #endif | 56 | #endif |
diff --git a/kernel/exit.c b/kernel/exit.c index a5bf5329ff97..35401720635b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -396,7 +396,7 @@ void daemonize(const char *name, ...) | |||
396 | current->fs = fs; | 396 | current->fs = fs; |
397 | atomic_inc(&fs->count); | 397 | atomic_inc(&fs->count); |
398 | 398 | ||
399 | put_and_finalize_nsproxy(current->nsproxy); | 399 | exit_task_namespaces(current); |
400 | current->nsproxy = init_task.nsproxy; | 400 | current->nsproxy = init_task.nsproxy; |
401 | get_task_namespaces(current); | 401 | get_task_namespaces(current); |
402 | 402 | ||
@@ -853,7 +853,6 @@ static void exit_notify(struct task_struct *tsk) | |||
853 | fastcall NORET_TYPE void do_exit(long code) | 853 | fastcall NORET_TYPE void do_exit(long code) |
854 | { | 854 | { |
855 | struct task_struct *tsk = current; | 855 | struct task_struct *tsk = current; |
856 | struct nsproxy *ns; | ||
857 | int group_dead; | 856 | int group_dead; |
858 | 857 | ||
859 | profile_task_exit(tsk); | 858 | profile_task_exit(tsk); |
@@ -939,9 +938,8 @@ fastcall NORET_TYPE void do_exit(long code) | |||
939 | 938 | ||
940 | tsk->exit_code = code; | 939 | tsk->exit_code = code; |
941 | proc_exit_connector(tsk); | 940 | proc_exit_connector(tsk); |
942 | ns = preexit_task_namespaces(tsk); | ||
943 | exit_notify(tsk); | 941 | exit_notify(tsk); |
944 | exit_task_namespaces(tsk, ns); | 942 | exit_task_namespaces(tsk); |
945 | #ifdef CONFIG_NUMA | 943 | #ifdef CONFIG_NUMA |
946 | mpol_free(tsk->mempolicy); | 944 | mpol_free(tsk->mempolicy); |
947 | tsk->mempolicy = NULL; | 945 | tsk->mempolicy = NULL; |
diff --git a/kernel/fork.c b/kernel/fork.c index 4cf868458f06..fc723e595cd5 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1265,7 +1265,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1265 | return p; | 1265 | return p; |
1266 | 1266 | ||
1267 | bad_fork_cleanup_namespaces: | 1267 | bad_fork_cleanup_namespaces: |
1268 | put_and_finalize_nsproxy(p->nsproxy); | 1268 | exit_task_namespaces(p); |
1269 | bad_fork_cleanup_keys: | 1269 | bad_fork_cleanup_keys: |
1270 | exit_keys(p); | 1270 | exit_keys(p); |
1271 | bad_fork_cleanup_mm: | 1271 | bad_fork_cleanup_mm: |
@@ -1711,7 +1711,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1711 | } | 1711 | } |
1712 | 1712 | ||
1713 | if (new_nsproxy) | 1713 | if (new_nsproxy) |
1714 | put_and_finalize_nsproxy(new_nsproxy); | 1714 | put_nsproxy(new_nsproxy); |
1715 | 1715 | ||
1716 | bad_unshare_cleanup_ipc: | 1716 | bad_unshare_cleanup_ipc: |
1717 | if (new_ipc) | 1717 | if (new_ipc) |
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 7b05bce75cde..f5b9ee6f6bbb 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -117,7 +117,7 @@ int copy_namespaces(int flags, struct task_struct *tsk) | |||
117 | goto out_pid; | 117 | goto out_pid; |
118 | 118 | ||
119 | out: | 119 | out: |
120 | put_and_finalize_nsproxy(old_ns); | 120 | put_nsproxy(old_ns); |
121 | return err; | 121 | return err; |
122 | 122 | ||
123 | out_pid: | 123 | out_pid: |
@@ -135,20 +135,6 @@ out_ns: | |||
135 | goto out; | 135 | goto out; |
136 | } | 136 | } |
137 | 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 | } | ||
151 | |||
152 | void free_nsproxy(struct nsproxy *ns) | 138 | void free_nsproxy(struct nsproxy *ns) |
153 | { | 139 | { |
154 | if (ns->mnt_ns) | 140 | if (ns->mnt_ns) |