47
47
#include <linux/cgroup.h>
48
48
#include <linux/audit.h>
49
49
#include <linux/sysctl.h>
50
+ #include <uapi/linux/pidfd.h>
50
51
51
52
#define CREATE_TRACE_POINTS
52
53
#include <trace/events/signal.h>
@@ -1436,7 +1437,8 @@ void lockdep_assert_task_sighand_held(struct task_struct *task)
1436
1437
#endif
1437
1438
1438
1439
/*
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.
1440
1442
*/
1441
1443
int group_send_sig_info (int sig , struct kernel_siginfo * info ,
1442
1444
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)
1478
1480
return ret ;
1479
1481
}
1480
1482
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 )
1482
1485
{
1483
1486
int error = - ESRCH ;
1484
1487
struct task_struct * p ;
@@ -1487,11 +1490,10 @@ int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid)
1487
1490
rcu_read_lock ();
1488
1491
p = pid_task (pid , PIDTYPE_PID );
1489
1492
if (p )
1490
- error = group_send_sig_info (sig , info , p , PIDTYPE_TGID );
1493
+ error = group_send_sig_info (sig , info , p , type );
1491
1494
rcu_read_unlock ();
1492
1495
if (likely (!p || error != - ESRCH ))
1493
1496
return error ;
1494
-
1495
1497
/*
1496
1498
* The task was unhashed in between, try again. If it
1497
1499
* 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)
1500
1502
}
1501
1503
}
1502
1504
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
+
1503
1510
static int kill_proc_info (int sig , struct kernel_siginfo * info , pid_t pid )
1504
1511
{
1505
1512
int error ;
@@ -3873,14 +3880,10 @@ static struct pid *pidfd_to_pid(const struct file *file)
3873
3880
* @info: signal info
3874
3881
* @flags: future flags
3875
3882
*
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.
3884
3887
*
3885
3888
* Return: 0 on success, negative errno on failure
3886
3889
*/
@@ -3891,6 +3894,7 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
3891
3894
struct fd f ;
3892
3895
struct pid * pid ;
3893
3896
kernel_siginfo_t kinfo ;
3897
+ enum pid_type type ;
3894
3898
3895
3899
/* Enforce flags be set to 0 until we add an extension. */
3896
3900
if (flags )
@@ -3911,6 +3915,11 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
3911
3915
if (!access_pidfd_pidns (pid ))
3912
3916
goto err ;
3913
3917
3918
+ if (f .file -> f_flags & PIDFD_THREAD )
3919
+ type = PIDTYPE_PID ;
3920
+ else
3921
+ type = PIDTYPE_TGID ;
3922
+
3914
3923
if (info ) {
3915
3924
ret = copy_siginfo_from_user_any (& kinfo , info );
3916
3925
if (unlikely (ret ))
@@ -3926,12 +3935,10 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
3926
3935
(kinfo .si_code >= 0 || kinfo .si_code == SI_TKILL ))
3927
3936
goto err ;
3928
3937
} else {
3929
- prepare_kill_siginfo (sig , & kinfo , PIDTYPE_TGID );
3938
+ prepare_kill_siginfo (sig , & kinfo , type );
3930
3939
}
3931
3940
3932
- /* TODO: respect PIDFD_THREAD */
3933
- ret = kill_pid_info (sig , & kinfo , pid );
3934
-
3941
+ ret = kill_pid_info_type (sig , & kinfo , pid , type );
3935
3942
err :
3936
3943
fdput (f );
3937
3944
return ret ;
0 commit comments