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 051f090d40c1..e2cd3e2a5ae8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/user-return-notifier.h> | 66 | #include <linux/user-return-notifier.h> |
67 | #include <linux/oom.h> | 67 | #include <linux/oom.h> |
68 | #include <linux/khugepaged.h> | 68 | #include <linux/khugepaged.h> |
69 | #include <linux/signalfd.h> | ||
69 | 70 | ||
70 | #include <asm/pgtable.h> | 71 | #include <asm/pgtable.h> |
71 | #include <asm/pgalloc.h> | 72 | #include <asm/pgalloc.h> |
@@ -647,6 +648,26 @@ struct mm_struct *get_task_mm(struct task_struct *task) | |||
647 | } | 648 | } |
648 | EXPORT_SYMBOL_GPL(get_task_mm); | 649 | EXPORT_SYMBOL_GPL(get_task_mm); |
649 | 650 | ||
651 | struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) | ||
652 | { | ||
653 | struct mm_struct *mm; | ||
654 | int err; | ||
655 | |||
656 | err = mutex_lock_killable(&task->signal->cred_guard_mutex); | ||
657 | if (err) | ||
658 | return ERR_PTR(err); | ||
659 | |||
660 | mm = get_task_mm(task); | ||
661 | if (mm && mm != current->mm && | ||
662 | !ptrace_may_access(task, mode)) { | ||
663 | mmput(mm); | ||
664 | mm = ERR_PTR(-EACCES); | ||
665 | } | ||
666 | mutex_unlock(&task->signal->cred_guard_mutex); | ||
667 | |||
668 | return mm; | ||
669 | } | ||
670 | |||
650 | /* Please note the differences between mmput and mm_release. | 671 | /* Please note the differences between mmput and mm_release. |
651 | * mmput is called whenever we stop holding onto a mm_struct, | 672 | * mmput is called whenever we stop holding onto a mm_struct, |
652 | * error success whatever. | 673 | * error success whatever. |
@@ -890,7 +911,7 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk) | |||
890 | return -ENOMEM; | 911 | return -ENOMEM; |
891 | 912 | ||
892 | new_ioc->ioprio = ioc->ioprio; | 913 | new_ioc->ioprio = ioc->ioprio; |
893 | put_io_context(new_ioc, NULL); | 914 | put_io_context(new_ioc); |
894 | } | 915 | } |
895 | #endif | 916 | #endif |
896 | return 0; | 917 | return 0; |
@@ -915,8 +936,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) | |||
915 | 936 | ||
916 | void __cleanup_sighand(struct sighand_struct *sighand) | 937 | void __cleanup_sighand(struct sighand_struct *sighand) |
917 | { | 938 | { |
918 | if (atomic_dec_and_test(&sighand->count)) | 939 | if (atomic_dec_and_test(&sighand->count)) { |
940 | signalfd_cleanup(sighand); | ||
919 | kmem_cache_free(sighand_cachep, sighand); | 941 | kmem_cache_free(sighand_cachep, sighand); |
942 | } | ||
920 | } | 943 | } |
921 | 944 | ||
922 | 945 | ||