UPSTREAM: signal: don't silently convert SI_USER signals to non-current pidfd
authorJann Horn <jannh@google.com>
Sat, 30 Mar 2019 02:12:32 +0000 (03:12 +0100)
committerlingsen1 <lingsen1@lenovo.com>
Sun, 7 Feb 2021 09:37:09 +0000 (17:37 +0800)
The current sys_pidfd_send_signal() silently turns signals with explicit
SI_USER context that are sent to non-current tasks into signals with
kernel-generated siginfo.
This is unl(CR) do_rt_sigqueueinfo(), which returns -EPERM in this case.
If a user actually wants to send a signal with kernel-provided siginfo,
they can do that with pidfd_send_signal(pidfd, sig, NULL, 0); so allowing
this case is unnecessary.

Instead of silently replacing the siginfo, just bail out with an error;
this is consistent with other interfaces and avoids special-casing behavior
based on security checks.

Fixes: 3eb39f47934f ("signal: add pidfd_send_signal() syscall")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian Brauner <christian@brauner.io>
(cherry picked from commit 556a888a14afe27164191955618990fb3ccc9aad)

Mot-CRs-fixed: (CR)

Bug: 135608568
Test: test program using syscall(__NR_pidfd_send_signal,..) to send SIGKILL
Change-Id: I493af671b82c43bff1425ee24550d2fb9aa6d961
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-on: https://gerrit.mot.com/1505848
Tested-by: Jira Key
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Reviewed-by: Wang Wang <wangwang1@lenovo.com>
Reviewed-by: Yonghui Jia <jiayh2@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1796156
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
kernel/signal.c

index 037c24780dad211aac60d2cb9047eb1006dfad73..23ff00fe1d09dad24fa0a2a0884f0ca6218a2cb5 100644 (file)
@@ -3157,16 +3157,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
                if (unlikely(sig != kinfo.si_signo))
                        goto err;
 
+               /* Only allow sending arbitrary signals to yourself. */
+               ret = -EPERM;
                if ((task_pid(current) != pid) &&
-                   (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) {
-                       /* Only allow sending arbitrary signals to yourself. */
-                       ret = -EPERM;
-                       if (kinfo.si_code != SI_USER)
-                               goto err;
-
-                       /* Turn this into a regular kill signal. */
-                       prepare_kill_siginfo(sig, &kinfo);
-               }
+                   (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
+                       goto err;
        } else {
                prepare_kill_siginfo(sig, &kinfo);
        }