diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2013-03-09 19:15:23 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-08-30 20:30:38 -0400 |
commit | dbef0c1c4c5f8ce5d1f5bd8cee092a7afb4ac21b (patch) | |
tree | 3eaa0a5a45ba52fae938e42e0031f25ac96a482f /kernel/nsproxy.c | |
parent | a606488513543312805fab2b93070cefe6a3016c (diff) |
namespaces: Simplify copy_namespaces so it is clear what is going on.
Remove the test for the impossible case where tsk->nsproxy == NULL. Fork
will never be called with tsk->nsproxy == NULL.
Only call get_nsproxy when we don't need to generate a new_nsproxy,
and mark the case where we don't generate a new nsproxy as likely.
Remove the code to drop an unnecessarily acquired nsproxy value.
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'kernel/nsproxy.c')
-rw-r--r-- | kernel/nsproxy.c | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index d9afd256318f..a1ed01139276 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -125,22 +125,16 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) | |||
125 | struct nsproxy *old_ns = tsk->nsproxy; | 125 | struct nsproxy *old_ns = tsk->nsproxy; |
126 | struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); | 126 | struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); |
127 | struct nsproxy *new_ns; | 127 | struct nsproxy *new_ns; |
128 | int err = 0; | ||
129 | 128 | ||
130 | if (!old_ns) | 129 | if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
130 | CLONE_NEWPID | CLONE_NEWNET)))) { | ||
131 | get_nsproxy(old_ns); | ||
131 | return 0; | 132 | return 0; |
132 | |||
133 | get_nsproxy(old_ns); | ||
134 | |||
135 | if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | | ||
136 | CLONE_NEWPID | CLONE_NEWNET))) | ||
137 | return 0; | ||
138 | |||
139 | if (!ns_capable(user_ns, CAP_SYS_ADMIN)) { | ||
140 | err = -EPERM; | ||
141 | goto out; | ||
142 | } | 133 | } |
143 | 134 | ||
135 | if (!ns_capable(user_ns, CAP_SYS_ADMIN)) | ||
136 | return -EPERM; | ||
137 | |||
144 | /* | 138 | /* |
145 | * CLONE_NEWIPC must detach from the undolist: after switching | 139 | * CLONE_NEWIPC must detach from the undolist: after switching |
146 | * to a new ipc namespace, the semaphore arrays from the old | 140 | * to a new ipc namespace, the semaphore arrays from the old |
@@ -149,22 +143,15 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) | |||
149 | * it along with CLONE_NEWIPC. | 143 | * it along with CLONE_NEWIPC. |
150 | */ | 144 | */ |
151 | if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == | 145 | if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == |
152 | (CLONE_NEWIPC | CLONE_SYSVSEM)) { | 146 | (CLONE_NEWIPC | CLONE_SYSVSEM)) |
153 | err = -EINVAL; | 147 | return -EINVAL; |
154 | goto out; | ||
155 | } | ||
156 | 148 | ||
157 | new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); | 149 | new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); |
158 | if (IS_ERR(new_ns)) { | 150 | if (IS_ERR(new_ns)) |
159 | err = PTR_ERR(new_ns); | 151 | return PTR_ERR(new_ns); |
160 | goto out; | ||
161 | } | ||
162 | 152 | ||
163 | tsk->nsproxy = new_ns; | 153 | tsk->nsproxy = new_ns; |
164 | 154 | return 0; | |
165 | out: | ||
166 | put_nsproxy(old_ns); | ||
167 | return err; | ||
168 | } | 155 | } |
169 | 156 | ||
170 | void free_nsproxy(struct nsproxy *ns) | 157 | void free_nsproxy(struct nsproxy *ns) |