diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 20 | 
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index c36c4e301ef..c535f33bbb9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -146,7 +146,7 @@ void __weak arch_release_thread_info(struct thread_info *ti)  static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,  						  int node)  { -	struct page *page = alloc_pages_node(node, THREADINFO_GFP, +	struct page *page = alloc_pages_node(node, THREADINFO_GFP_ACCOUNTED,  					     THREAD_SIZE_ORDER);  	return page ? page_address(page) : NULL; @@ -154,7 +154,7 @@ static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,  static inline void free_thread_info(struct thread_info *ti)  { -	free_pages((unsigned long)ti, THREAD_SIZE_ORDER); +	free_memcg_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER);  }  # else  static struct kmem_cache *thread_info_cache; @@ -1166,6 +1166,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,  				current->signal->flags & SIGNAL_UNKILLABLE)  		return ERR_PTR(-EINVAL); +	/* +	 * If the new process will be in a different pid namespace +	 * don't allow the creation of threads. +	 */ +	if ((clone_flags & (CLONE_VM|CLONE_NEWPID)) && +	    (task_active_pid_ns(current) != current->nsproxy->pid_ns)) +		return ERR_PTR(-EINVAL); +  	retval = security_task_create(clone_flags);  	if (retval)  		goto fork_out; @@ -1613,7 +1621,6 @@ long do_fork(unsigned long clone_flags,  	return nr;  } -#ifdef CONFIG_GENERIC_KERNEL_THREAD  /*   * Create a kernel thread.   */ @@ -1622,7 +1629,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)  	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,  		(unsigned long)arg, NULL, NULL);  } -#endif  #ifdef __ARCH_WANT_SYS_FORK  SYSCALL_DEFINE0(fork) @@ -1662,8 +1668,10 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,  		 int, tls_val)  #endif  { -	return do_fork(clone_flags, newsp, 0, -		parent_tidptr, child_tidptr); +	long ret = do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr); +	asmlinkage_protect(5, ret, clone_flags, newsp, +			parent_tidptr, child_tidptr, tls_val); +	return ret;  }  #endif  |