diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 27 | 
1 files changed, 25 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 051f090d40c..e2cd3e2a5ae 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -66,6 +66,7 @@  #include <linux/user-return-notifier.h>  #include <linux/oom.h>  #include <linux/khugepaged.h> +#include <linux/signalfd.h>  #include <asm/pgtable.h>  #include <asm/pgalloc.h> @@ -647,6 +648,26 @@ struct mm_struct *get_task_mm(struct task_struct *task)  }  EXPORT_SYMBOL_GPL(get_task_mm); +struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) +{ +	struct mm_struct *mm; +	int err; + +	err =  mutex_lock_killable(&task->signal->cred_guard_mutex); +	if (err) +		return ERR_PTR(err); + +	mm = get_task_mm(task); +	if (mm && mm != current->mm && +			!ptrace_may_access(task, mode)) { +		mmput(mm); +		mm = ERR_PTR(-EACCES); +	} +	mutex_unlock(&task->signal->cred_guard_mutex); + +	return mm; +} +  /* Please note the differences between mmput and mm_release.   * mmput is called whenever we stop holding onto a mm_struct,   * error success whatever. @@ -890,7 +911,7 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)  			return -ENOMEM;  		new_ioc->ioprio = ioc->ioprio; -		put_io_context(new_ioc, NULL); +		put_io_context(new_ioc);  	}  #endif  	return 0; @@ -915,8 +936,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)  void __cleanup_sighand(struct sighand_struct *sighand)  { -	if (atomic_dec_and_test(&sighand->count)) +	if (atomic_dec_and_test(&sighand->count)) { +		signalfd_cleanup(sighand);  		kmem_cache_free(sighand_cachep, sighand); +	}  }  | 
