diff options
Diffstat (limited to 'kernel/nsproxy.c')
| -rw-r--r-- | kernel/nsproxy.c | 23 | 
1 files changed, 21 insertions, 2 deletions
| diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index eec72ca962e2..a487ff24129b 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -157,7 +157,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)  	if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |  			      CLONE_NEWPID | CLONE_NEWNET |  			      CLONE_NEWCGROUP | CLONE_NEWTIME)))) { -		if (likely(old_ns->time_ns_for_children == old_ns->time_ns)) { +		if ((flags & CLONE_VM) || +		    likely(old_ns->time_ns_for_children == old_ns->time_ns)) {  			get_nsproxy(old_ns);  			return 0;  		} @@ -179,7 +180,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)  	if (IS_ERR(new_ns))  		return  PTR_ERR(new_ns); -	timens_on_fork(new_ns, tsk); +	if ((flags & CLONE_VM) == 0) +		timens_on_fork(new_ns, tsk);  	tsk->nsproxy = new_ns;  	return 0; @@ -254,6 +256,23 @@ void exit_task_namespaces(struct task_struct *p)  	switch_task_namespaces(p, NULL);  } +int exec_task_namespaces(void) +{ +	struct task_struct *tsk = current; +	struct nsproxy *new; + +	if (tsk->nsproxy->time_ns_for_children == tsk->nsproxy->time_ns) +		return 0; + +	new = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs); +	if (IS_ERR(new)) +		return PTR_ERR(new); + +	timens_on_fork(new, tsk); +	switch_task_namespaces(tsk, new); +	return 0; +} +  static int check_setns_flags(unsigned long flags)  {  	if (!flags || (flags & ~(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |