You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge sys_clone()/sys_unshare() nsproxy and namespace handling
sys_clone() and sys_unshare() both makes copies of nsproxy and its associated namespaces. But they have different code paths. This patch merges all the nsproxy and its associated namespace copy/clone handling (as much as possible). Posted on container list earlier for feedback. - Create a new nsproxy and its associated namespaces and pass it back to caller to attach it to right process. - Changed all copy_*_ns() routines to return a new copy of namespace instead of attaching it to task->nsproxy. - Moved the CAP_SYS_ADMIN checks out of copy_*_ns() routines. - Removed unnessary !ns checks from copy_*_ns() and added BUG_ON() just incase. - Get rid of all individual unshare_*_ns() routines and make use of copy_*_ns() instead. [akpm@osdl.org: cleanups, warning fix] [clg@fr.ibm.com: remove dup_namespaces() declaration] [serue@us.ibm.com: fix CONFIG_IPC_NS=n, clone(CLONE_NEWIPC) retval] [akpm@linux-foundation.org: fix build with CONFIG_SYSVIPC=n] Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Serge Hallyn <serue@us.ibm.com> Cc: Cedric Le Goater <clg@fr.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: <containers@lists.osdl.org> Signed-off-by: Cedric Le Goater <clg@fr.ibm.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
4fc75ff481
commit
e3222c4ecc
+5
-80
@@ -1515,26 +1515,6 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unshare the mnt_namespace structure if it is being shared
|
||||
*/
|
||||
static int unshare_mnt_namespace(unsigned long unshare_flags,
|
||||
struct mnt_namespace **new_nsp, struct fs_struct *new_fs)
|
||||
{
|
||||
struct mnt_namespace *ns = current->nsproxy->mnt_ns;
|
||||
|
||||
if ((unshare_flags & CLONE_NEWNS) && ns) {
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
*new_nsp = dup_mnt_ns(current, new_fs ? new_fs : current->fs);
|
||||
if (!*new_nsp)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsharing of sighand is not supported yet
|
||||
*/
|
||||
@@ -1593,16 +1573,6 @@ static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **n
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IPC_NS
|
||||
static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
|
||||
{
|
||||
if (flags & CLONE_NEWIPC)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* unshare allows a process to 'unshare' part of the process
|
||||
* context which was originally shared using clone. copy_*
|
||||
@@ -1615,14 +1585,11 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
|
||||
{
|
||||
int err = 0;
|
||||
struct fs_struct *fs, *new_fs = NULL;
|
||||
struct mnt_namespace *ns, *new_ns = NULL;
|
||||
struct sighand_struct *new_sigh = NULL;
|
||||
struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
|
||||
struct files_struct *fd, *new_fd = NULL;
|
||||
struct sem_undo_list *new_ulist = NULL;
|
||||
struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
|
||||
struct uts_namespace *uts, *new_uts = NULL;
|
||||
struct ipc_namespace *ipc, *new_ipc = NULL;
|
||||
|
||||
check_unshare_flags(&unshare_flags);
|
||||
|
||||
@@ -1637,36 +1604,24 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
|
||||
goto bad_unshare_out;
|
||||
if ((err = unshare_fs(unshare_flags, &new_fs)))
|
||||
goto bad_unshare_cleanup_thread;
|
||||
if ((err = unshare_mnt_namespace(unshare_flags, &new_ns, new_fs)))
|
||||
goto bad_unshare_cleanup_fs;
|
||||
if ((err = unshare_sighand(unshare_flags, &new_sigh)))
|
||||
goto bad_unshare_cleanup_ns;
|
||||
goto bad_unshare_cleanup_fs;
|
||||
if ((err = unshare_vm(unshare_flags, &new_mm)))
|
||||
goto bad_unshare_cleanup_sigh;
|
||||
if ((err = unshare_fd(unshare_flags, &new_fd)))
|
||||
goto bad_unshare_cleanup_vm;
|
||||
if ((err = unshare_semundo(unshare_flags, &new_ulist)))
|
||||
goto bad_unshare_cleanup_fd;
|
||||
if ((err = unshare_utsname(unshare_flags, &new_uts)))
|
||||
if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
|
||||
new_fs)))
|
||||
goto bad_unshare_cleanup_semundo;
|
||||
if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
|
||||
goto bad_unshare_cleanup_uts;
|
||||
|
||||
if (new_ns || new_uts || new_ipc) {
|
||||
old_nsproxy = current->nsproxy;
|
||||
new_nsproxy = dup_namespaces(old_nsproxy);
|
||||
if (!new_nsproxy) {
|
||||
err = -ENOMEM;
|
||||
goto bad_unshare_cleanup_ipc;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_fs || new_ns || new_mm || new_fd || new_ulist ||
|
||||
new_uts || new_ipc) {
|
||||
if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) {
|
||||
|
||||
task_lock(current);
|
||||
|
||||
if (new_nsproxy) {
|
||||
old_nsproxy = current->nsproxy;
|
||||
current->nsproxy = new_nsproxy;
|
||||
new_nsproxy = old_nsproxy;
|
||||
}
|
||||
@@ -1677,12 +1632,6 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
|
||||
new_fs = fs;
|
||||
}
|
||||
|
||||
if (new_ns) {
|
||||
ns = current->nsproxy->mnt_ns;
|
||||
current->nsproxy->mnt_ns = new_ns;
|
||||
new_ns = ns;
|
||||
}
|
||||
|
||||
if (new_mm) {
|
||||
mm = current->mm;
|
||||
active_mm = current->active_mm;
|
||||
@@ -1698,32 +1647,12 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
|
||||
new_fd = fd;
|
||||
}
|
||||
|
||||
if (new_uts) {
|
||||
uts = current->nsproxy->uts_ns;
|
||||
current->nsproxy->uts_ns = new_uts;
|
||||
new_uts = uts;
|
||||
}
|
||||
|
||||
if (new_ipc) {
|
||||
ipc = current->nsproxy->ipc_ns;
|
||||
current->nsproxy->ipc_ns = new_ipc;
|
||||
new_ipc = ipc;
|
||||
}
|
||||
|
||||
task_unlock(current);
|
||||
}
|
||||
|
||||
if (new_nsproxy)
|
||||
put_nsproxy(new_nsproxy);
|
||||
|
||||
bad_unshare_cleanup_ipc:
|
||||
if (new_ipc)
|
||||
put_ipc_ns(new_ipc);
|
||||
|
||||
bad_unshare_cleanup_uts:
|
||||
if (new_uts)
|
||||
put_uts_ns(new_uts);
|
||||
|
||||
bad_unshare_cleanup_semundo:
|
||||
bad_unshare_cleanup_fd:
|
||||
if (new_fd)
|
||||
@@ -1738,10 +1667,6 @@ bad_unshare_cleanup_sigh:
|
||||
if (atomic_dec_and_test(&new_sigh->count))
|
||||
kmem_cache_free(sighand_cachep, new_sigh);
|
||||
|
||||
bad_unshare_cleanup_ns:
|
||||
if (new_ns)
|
||||
put_mnt_ns(new_ns);
|
||||
|
||||
bad_unshare_cleanup_fs:
|
||||
if (new_fs)
|
||||
put_fs_struct(new_fs);
|
||||
|
||||
Reference in New Issue
Block a user