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>
This commit is contained in:
Eric W. Biederman 2013-03-09 16:15:23 -08:00
parent a606488513
commit dbef0c1c4c
1 changed files with 11 additions and 24 deletions

View File

@ -125,22 +125,16 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
struct nsproxy *old_ns = tsk->nsproxy; struct nsproxy *old_ns = tsk->nsproxy;
struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
struct nsproxy *new_ns; struct nsproxy *new_ns;
int err = 0;
if (!old_ns) if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWPID | CLONE_NEWNET)))) {
get_nsproxy(old_ns);
return 0; return 0;
get_nsproxy(old_ns);
if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWPID | CLONE_NEWNET)))
return 0;
if (!ns_capable(user_ns, CAP_SYS_ADMIN)) {
err = -EPERM;
goto out;
} }
if (!ns_capable(user_ns, CAP_SYS_ADMIN))
return -EPERM;
/* /*
* CLONE_NEWIPC must detach from the undolist: after switching * CLONE_NEWIPC must detach from the undolist: after switching
* to a new ipc namespace, the semaphore arrays from the old * 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)
* it along with CLONE_NEWIPC. * it along with CLONE_NEWIPC.
*/ */
if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
(CLONE_NEWIPC | CLONE_SYSVSEM)) { (CLONE_NEWIPC | CLONE_SYSVSEM))
err = -EINVAL; return -EINVAL;
goto out;
}
new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
if (IS_ERR(new_ns)) { if (IS_ERR(new_ns))
err = PTR_ERR(new_ns); return PTR_ERR(new_ns);
goto out;
}
tsk->nsproxy = new_ns; tsk->nsproxy = new_ns;
return 0;
out:
put_nsproxy(old_ns);
return err;
} }
void free_nsproxy(struct nsproxy *ns) void free_nsproxy(struct nsproxy *ns)