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 */
14411443int 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+
15031510static 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 );
39353942err :
39363943 fdput (f );
39373944 return ret ;
0 commit comments