[PATCH] signal: disallow non-SI_USER signals in pidfd_send_signal()

From: Christian Brauner
Date: Fri Feb 16 2024 - 07:21:11 EST


Oleg pointed out that the following condition:

/* Only allow sending arbitrary signals to yourself. */
ret = -EPERM;
if ((task_pid(current) != pid) &&
(kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
goto err;

doesn't account for PIDFD_SIGNAL_PROCESS_GROUP. He suggested:

/* Only allow sending arbitrary signals to yourself. */
ret = -EPERM;
if ((task_pid(current) != pid || type == PIDTYPE_PGID) &&
(kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)
goto err;

but I think we should just go all the way and error out if userspace
specifies anything else than SI_USER as si_code. It's probably an unused
feature right now anyway and if someone needs it than it's easy to add
back.

Reported-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Link: https://lore.kernel.org/r/20240214123655.GB16265@xxxxxxxxxx
Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx>
---
kernel/signal.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index cf6539a6b1cb..92a80e8d6b22 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3954,10 +3954,7 @@ 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))
+ if (kinfo.si_code != SI_USER)
goto err;
} else {
prepare_kill_siginfo(sig, &kinfo, type);
--
2.43.0


--xjc36g5iq2xly2w4--