aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/entry/syscalls/syscall_32.tbl1
-rw-r--r--arch/x86/entry/syscalls/syscall_64.tbl1
-rw-r--r--fs/proc/base.c9
-rw-r--r--include/linux/proc_fs.h6
-rw-r--r--include/linux/syscalls.h3
-rw-r--r--include/uapi/asm-generic/unistd.h2
-rw-r--r--kernel/signal.c133
-rw-r--r--kernel/sys_ni.c1
-rw-r--r--tools/testing/selftests/Makefile1
-rw-r--r--tools/testing/selftests/pidfd/Makefile6
-rw-r--r--tools/testing/selftests/pidfd/pidfd_test.c381
11 files changed, 538 insertions, 6 deletions
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 8da78595d69d..1f9607ed087c 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -429,6 +429,7 @@
429421 i386 rt_sigtimedwait_time64 sys_rt_sigtimedwait __ia32_compat_sys_rt_sigtimedwait_time64 429421 i386 rt_sigtimedwait_time64 sys_rt_sigtimedwait __ia32_compat_sys_rt_sigtimedwait_time64
430422 i386 futex_time64 sys_futex __ia32_sys_futex 430422 i386 futex_time64 sys_futex __ia32_sys_futex
431423 i386 sched_rr_get_interval_time64 sys_sched_rr_get_interval __ia32_sys_sched_rr_get_interval 431423 i386 sched_rr_get_interval_time64 sys_sched_rr_get_interval __ia32_sys_sched_rr_get_interval
432424 i386 pidfd_send_signal sys_pidfd_send_signal __ia32_sys_pidfd_send_signal
432425 i386 io_uring_setup sys_io_uring_setup __ia32_sys_io_uring_setup 433425 i386 io_uring_setup sys_io_uring_setup __ia32_sys_io_uring_setup
433426 i386 io_uring_enter sys_io_uring_enter __ia32_sys_io_uring_enter 434426 i386 io_uring_enter sys_io_uring_enter __ia32_sys_io_uring_enter
434427 i386 io_uring_register sys_io_uring_register __ia32_sys_io_uring_register 435427 i386 io_uring_register sys_io_uring_register __ia32_sys_io_uring_register
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index c768447f97ec..92ee0b4378d4 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -345,6 +345,7 @@
345334 common rseq __x64_sys_rseq 345334 common rseq __x64_sys_rseq
346# don't use numbers 387 through 423, add new calls after the last 346# don't use numbers 387 through 423, add new calls after the last
347# 'common' entry 347# 'common' entry
348424 common pidfd_send_signal __x64_sys_pidfd_send_signal
348425 common io_uring_setup __x64_sys_io_uring_setup 349425 common io_uring_setup __x64_sys_io_uring_setup
349426 common io_uring_enter __x64_sys_io_uring_enter 350426 common io_uring_enter __x64_sys_io_uring_enter
350427 common io_uring_register __x64_sys_io_uring_register 351427 common io_uring_register __x64_sys_io_uring_register
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f5ebdd87afb2..ddef482f1334 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3074,6 +3074,15 @@ static const struct file_operations proc_tgid_base_operations = {
3074 .llseek = generic_file_llseek, 3074 .llseek = generic_file_llseek,
3075}; 3075};
3076 3076
3077struct pid *tgid_pidfd_to_pid(const struct file *file)
3078{
3079 if (!d_is_dir(file->f_path.dentry) ||
3080 (file->f_op != &proc_tgid_base_operations))
3081 return ERR_PTR(-EBADF);
3082
3083 return proc_pid(file_inode(file));
3084}
3085
3077static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) 3086static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
3078{ 3087{
3079 return proc_pident_lookup(dir, dentry, 3088 return proc_pident_lookup(dir, dentry,
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index d0e1f1522a78..52a283ba0465 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -73,6 +73,7 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo
73 int (*show)(struct seq_file *, void *), 73 int (*show)(struct seq_file *, void *),
74 proc_write_t write, 74 proc_write_t write,
75 void *data); 75 void *data);
76extern struct pid *tgid_pidfd_to_pid(const struct file *file);
76 77
77#else /* CONFIG_PROC_FS */ 78#else /* CONFIG_PROC_FS */
78 79
@@ -114,6 +115,11 @@ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *p
114#define proc_create_net(name, mode, parent, state_size, ops) ({NULL;}) 115#define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
115#define proc_create_net_single(name, mode, parent, show, data) ({NULL;}) 116#define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
116 117
118static inline struct pid *tgid_pidfd_to_pid(const struct file *file)
119{
120 return ERR_PTR(-EBADF);
121}
122
117#endif /* CONFIG_PROC_FS */ 123#endif /* CONFIG_PROC_FS */
118 124
119struct net; 125struct net;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index c2962953bf11..e446806a561f 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -985,6 +985,9 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
985 unsigned mask, struct statx __user *buffer); 985 unsigned mask, struct statx __user *buffer);
986asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len, 986asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len,
987 int flags, uint32_t sig); 987 int flags, uint32_t sig);
988asmlinkage long sys_pidfd_send_signal(int pidfd, int sig,
989 siginfo_t __user *info,
990 unsigned int flags);
988 991
989/* 992/*
990 * Architecture-specific system calls 993 * Architecture-specific system calls
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index bf4624efe5e6..dee7292e1df6 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -824,6 +824,8 @@ __SYSCALL(__NR_futex_time64, sys_futex)
824__SYSCALL(__NR_sched_rr_get_interval_time64, sys_sched_rr_get_interval) 824__SYSCALL(__NR_sched_rr_get_interval_time64, sys_sched_rr_get_interval)
825#endif 825#endif
826 826
827#define __NR_pidfd_send_signal 424
828__SYSCALL(__NR_pidfd_send_signal, sys_pidfd_send_signal)
827#define __NR_io_uring_setup 425 829#define __NR_io_uring_setup 425
828__SYSCALL(__NR_io_uring_setup, sys_io_uring_setup) 830__SYSCALL(__NR_io_uring_setup, sys_io_uring_setup)
829#define __NR_io_uring_enter 426 831#define __NR_io_uring_enter 426
diff --git a/kernel/signal.c b/kernel/signal.c
index 5d53183e2705..b7953934aa99 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -19,7 +19,9 @@
19#include <linux/sched/task.h> 19#include <linux/sched/task.h>
20#include <linux/sched/task_stack.h> 20#include <linux/sched/task_stack.h>
21#include <linux/sched/cputime.h> 21#include <linux/sched/cputime.h>
22#include <linux/file.h>
22#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/proc_fs.h>
23#include <linux/tty.h> 25#include <linux/tty.h>
24#include <linux/binfmts.h> 26#include <linux/binfmts.h>
25#include <linux/coredump.h> 27#include <linux/coredump.h>
@@ -3487,6 +3489,16 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait_time32, compat_sigset_t __user *, uthese,
3487#endif 3489#endif
3488#endif 3490#endif
3489 3491
3492static inline void prepare_kill_siginfo(int sig, struct kernel_siginfo *info)
3493{
3494 clear_siginfo(info);
3495 info->si_signo = sig;
3496 info->si_errno = 0;
3497 info->si_code = SI_USER;
3498 info->si_pid = task_tgid_vnr(current);
3499 info->si_uid = from_kuid_munged(current_user_ns(), current_uid());
3500}
3501
3490/** 3502/**
3491 * sys_kill - send a signal to a process 3503 * sys_kill - send a signal to a process
3492 * @pid: the PID of the process 3504 * @pid: the PID of the process
@@ -3496,16 +3508,125 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
3496{ 3508{
3497 struct kernel_siginfo info; 3509 struct kernel_siginfo info;
3498 3510
3499 clear_siginfo(&info); 3511 prepare_kill_siginfo(sig, &info);
3500 info.si_signo = sig;
3501 info.si_errno = 0;
3502 info.si_code = SI_USER;
3503 info.si_pid = task_tgid_vnr(current);
3504 info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
3505 3512
3506 return kill_something_info(sig, &info, pid); 3513 return kill_something_info(sig, &info, pid);
3507} 3514}
3508 3515
3516#ifdef CONFIG_PROC_FS
3517/*
3518 * Verify that the signaler and signalee either are in the same pid namespace
3519 * or that the signaler's pid namespace is an ancestor of the signalee's pid
3520 * namespace.
3521 */
3522static bool access_pidfd_pidns(struct pid *pid)
3523{
3524 struct pid_namespace *active = task_active_pid_ns(current);
3525 struct pid_namespace *p = ns_of_pid(pid);
3526
3527 for (;;) {
3528 if (!p)
3529 return false;
3530 if (p == active)
3531 break;
3532 p = p->parent;
3533 }
3534
3535 return true;
3536}
3537
3538static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, siginfo_t *info)
3539{
3540#ifdef CONFIG_COMPAT
3541 /*
3542 * Avoid hooking up compat syscalls and instead handle necessary
3543 * conversions here. Note, this is a stop-gap measure and should not be
3544 * considered a generic solution.
3545 */
3546 if (in_compat_syscall())
3547 return copy_siginfo_from_user32(
3548 kinfo, (struct compat_siginfo __user *)info);
3549#endif
3550 return copy_siginfo_from_user(kinfo, info);
3551}
3552
3553/**
3554 * sys_pidfd_send_signal - send a signal to a process through a task file
3555 * descriptor
3556 * @pidfd: the file descriptor of the process
3557 * @sig: signal to be sent
3558 * @info: the signal info
3559 * @flags: future flags to be passed
3560