Skip to content

Commit 81b9d8a

Browse files
oleg-nesterovbrauner
authored andcommitted
pidfd: change pidfd_send_signal() to respect PIDFD_THREAD
Turn kill_pid_info() into kill_pid_info_type(), this allows to pass any pid_type to group_send_sig_info(), despite its name it should work fine even if type = PIDTYPE_PID. Change pidfd_send_signal() to use PIDTYPE_PID or PIDTYPE_TGID depending on PIDFD_THREAD. While at it kill another TODO comment in pidfd_show_fdinfo(). As Christian expains fdinfo reports f_flags, userspace can already detect PIDFD_THREAD. Reviewed-by: Tycho Andersen <[email protected]> Signed-off-by: Oleg Nesterov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent c044a95 commit 81b9d8a

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

kernel/fork.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,8 +2051,6 @@ static void pidfd_show_fdinfo(struct seq_file *m, struct file *f)
20512051

20522052
seq_put_decimal_ll(m, "Pid:\t", nr);
20532053

2054-
/* TODO: report PIDFD_THREAD */
2055-
20562054
#ifdef CONFIG_PID_NS
20572055
seq_put_decimal_ll(m, "\nNSpid:\t", nr);
20582056
if (nr > 0) {

kernel/signal.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <linux/cgroup.h>
4848
#include <linux/audit.h>
4949
#include <linux/sysctl.h>
50+
#include <uapi/linux/pidfd.h>
5051

5152
#define CREATE_TRACE_POINTS
5253
#include <trace/events/signal.h>
@@ -1436,7 +1437,8 @@ void lockdep_assert_task_sighand_held(struct task_struct *task)
14361437
#endif
14371438

14381439
/*
1439-
* send signal info to all the members of a group
1440+
* send signal info to all the members of a thread group or to the
1441+
* individual thread if type == PIDTYPE_PID.
14401442
*/
14411443
int group_send_sig_info(int sig, struct kernel_siginfo *info,
14421444
struct task_struct *p, enum pid_type type)
@@ -1478,7 +1480,8 @@ int __kill_pgrp_info(int sig, struct kernel_siginfo *info, struct pid *pgrp)
14781480
return ret;
14791481
}
14801482

1481-
int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
1483+
static int kill_pid_info_type(int sig, struct kernel_siginfo *info,
1484+
struct pid *pid, enum pid_type type)
14821485
{
14831486
int error = -ESRCH;
14841487
struct task_struct *p;
@@ -1487,11 +1490,10 @@ int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
14871490
rcu_read_lock();
14881491
p = pid_task(pid, PIDTYPE_PID);
14891492
if (p)
1490-
error = group_send_sig_info(sig, info, p, PIDTYPE_TGID);
1493+
error = group_send_sig_info(sig, info, p, type);
14911494
rcu_read_unlock();
14921495
if (likely(!p || error != -ESRCH))
14931496
return error;
1494-
14951497
/*
14961498
* The task was unhashed in between, try again. If it
14971499
* is dead, pid_task() will return NULL, if we race with
@@ -1500,6 +1502,11 @@ int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
15001502
}
15011503
}
15021504

1505+
int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
1506+
{
1507+
return kill_pid_info_type(sig, info, pid, PIDTYPE_TGID);
1508+
}
1509+
15031510
static int kill_proc_info(int sig, struct kernel_siginfo *info, pid_t pid)
15041511
{
15051512
int error;
@@ -3873,14 +3880,10 @@ static struct pid *pidfd_to_pid(const struct file *file)
38733880
* @info: signal info
38743881
* @flags: future flags
38753882
*
3876-
* The syscall currently only signals via PIDTYPE_PID which covers
3877-
* kill(<positive-pid>, <signal>. It does not signal threads or process
3878-
* groups.
3879-
* In order to extend the syscall to threads and process groups the @flags
3880-
* argument should be used. In essence, the @flags argument will determine
3881-
* what is signaled and not the file descriptor itself. Put in other words,
3882-
* grouping is a property of the flags argument not a property of the file
3883-
* descriptor.
3883+
* Send the signal to the thread group or to the individual thread depending
3884+
* on PIDFD_THREAD.
3885+
* In the future extension to @flags may be used to override the default scope
3886+
* of @pidfd.
38843887
*
38853888
* Return: 0 on success, negative errno on failure
38863889
*/
@@ -3891,6 +3894,7 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
38913894
struct fd f;
38923895
struct pid *pid;
38933896
kernel_siginfo_t kinfo;
3897+
enum pid_type type;
38943898

38953899
/* Enforce flags be set to 0 until we add an extension. */
38963900
if (flags)
@@ -3911,6 +3915,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
39113915
if (!access_pidfd_pidns(pid))
39123916
goto err;
39133917

3918+
if (f.file->f_flags & PIDFD_THREAD)
3919+
type = PIDTYPE_PID;
3920+
else
3921+
type = PIDTYPE_TGID;
3922+
39143923
if (info) {
39153924
ret = copy_siginfo_from_user_any(&kinfo, info);
39163925
if (unlikely(ret))
@@ -3926,12 +3935,10 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
39263935
(kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
39273936
goto err;
39283937
} else {
3929-
prepare_kill_siginfo(sig, &kinfo, PIDTYPE_TGID);
3938+
prepare_kill_siginfo(sig, &kinfo, type);
39303939
}
39313940

3932-
/* TODO: respect PIDFD_THREAD */
3933-
ret = kill_pid_info(sig, &kinfo, pid);
3934-
3941+
ret = kill_pid_info_type(sig, &kinfo, pid, type);
39353942
err:
39363943
fdput(f);
39373944
return ret;

0 commit comments

Comments
 (0)