Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+11 -24
+11 -24
kernel/nsproxy.c
··· 125 125 struct nsproxy *old_ns = tsk->nsproxy; 126 126 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); 127 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 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 } 134 + 135 + if (!ns_capable(user_ns, CAP_SYS_ADMIN)) 136 + return -EPERM; 143 137 144 138 /* 145 139 * CLONE_NEWIPC must detach from the undolist: after switching ··· 143 149 * it along with CLONE_NEWIPC. 144 150 */ 145 151 if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == 146 - (CLONE_NEWIPC | CLONE_SYSVSEM)) { 147 - err = -EINVAL; 148 - goto out; 149 - } 152 + (CLONE_NEWIPC | CLONE_SYSVSEM)) 153 + return -EINVAL; 150 154 151 155 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); 152 - if (IS_ERR(new_ns)) { 153 - err = PTR_ERR(new_ns); 154 - goto out; 155 - } 156 + if (IS_ERR(new_ns)) 157 + return PTR_ERR(new_ns); 156 158 157 159 tsk->nsproxy = new_ns; 158 - 159 - out: 160 - put_nsproxy(old_ns); 161 - return err; 160 + return 0; 162 161 } 163 162 164 163 void free_nsproxy(struct nsproxy *ns)