aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index b7953934aa99..cd83cc376767 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3513,7 +3513,6 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
3513 return kill_something_info(sig, &info, pid); 3513 return kill_something_info(sig, &info, pid);
3514} 3514}
3515 3515
3516#ifdef CONFIG_PROC_FS
3517/* 3516/*
3518 * Verify that the signaler and signalee either are in the same pid namespace 3517 * Verify that the signaler and signalee either are in the same pid namespace
3519 * or that the signaler's pid namespace is an ancestor of the signalee's pid 3518 * or that the signaler's pid namespace is an ancestor of the signalee's pid
@@ -3550,6 +3549,14 @@ static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, siginfo_t *info)
3550 return copy_siginfo_from_user(kinfo, info); 3549 return copy_siginfo_from_user(kinfo, info);
3551} 3550}
3552 3551
3552static struct pid *pidfd_to_pid(const struct file *file)
3553{
3554 if (file->f_op == &pidfd_fops)
3555 return file->private_data;
3556
3557 return tgid_pidfd_to_pid(file);
3558}
3559
3553/** 3560/**
3554 * sys_pidfd_send_signal - send a signal to a process through a task file 3561 * sys_pidfd_send_signal - send a signal to a process through a task file
3555 * descriptor 3562 * descriptor
@@ -3581,12 +3588,12 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
3581 if (flags) 3588 if (flags)
3582 return -EINVAL; 3589 return -EINVAL;
3583 3590
3584 f = fdget_raw(pidfd); 3591 f = fdget(pidfd);
3585 if (!f.file) 3592 if (!f.file)
3586 return -EBADF; 3593 return -EBADF;
3587 3594
3588 /* Is this a pidfd? */ 3595 /* Is this a pidfd? */
3589 pid = tgid_pidfd_to_pid(f.file); 3596 pid = pidfd_to_pid(f.file);
3590 if (IS_ERR(pid)) { 3597 if (IS_ERR(pid)) {
3591 ret = PTR_ERR(pid); 3598 ret = PTR_ERR(pid);
3592 goto err; 3599 goto err;
@@ -3605,16 +3612,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
3605 if (unlikely(sig != kinfo.si_signo)) 3612 if (unlikely(sig != kinfo.si_signo))
3606 goto err; 3613 goto err;
3607 3614
3615 /* Only allow sending arbitrary signals to yourself. */
3616 ret = -EPERM;
3608 if ((task_pid(current) != pid) && 3617 if ((task_pid(current) != pid) &&
3609 (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) { 3618 (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
3610 /* Only allow sending arbitrary signals to yourself. */ 3619 goto err;
3611 ret = -EPERM;
3612 if (kinfo.si_code != SI_USER)
3613 goto err;
3614
3615 /* Turn this into a regular kill signal. */
3616 prepare_kill_siginfo(sig, &kinfo);
3617 }
3618 } else { 3620 } else {
3619 prepare_kill_siginfo(sig, &kinfo); 3621 prepare_kill_siginfo(sig, &kinfo);
3620 } 3622 }
@@ -3625,7 +3627,6 @@ err:
3625 fdput(f); 3627 fdput(f);
3626 return ret; 3628 return ret;
3627} 3629}
3628#endif /* CONFIG_PROC_FS */
3629 3630
3630static int 3631static int
3631do_send_specific(pid_t tgid, pid_t pid, int sig, struct kernel_siginfo *info) 3632do_send_specific(pid_t tgid, pid_t pid, int sig, struct kernel_siginfo *info)