From: Puranjay Mohan <puranjay@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
puranjay12@gmail.com
Subject: [PATCH bpf-next v2 1/2] bpf: implement bpf_send_signal_remote() kfunc
Date: Thu, 26 Sep 2024 11:53:27 +0000 [thread overview]
Message-ID: <20240926115328.105634-2-puranjay@kernel.org> (raw)
In-Reply-To: <20240926115328.105634-1-puranjay@kernel.org>
Implement bpf_send_signal_remote kfunc that is similar to
bpf_send_signal_thread and bpf_send_signal helpers but can be used to
send signals to other threads and processes. It also supports sending a
cookie with the signal similar to sigqueue().
If the receiving process establishes a handler for the signal using the
SA_SIGINFO flag to sigaction(), then it can obtain this cookie via the
si_value field of the siginfo_t structure passed as the second argument
to the handler.
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
---
kernel/trace/bpf_trace.c | 78 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index a582cd25ca876..51b27db1321fc 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -802,6 +802,9 @@ struct send_signal_irq_work {
struct task_struct *task;
u32 sig;
enum pid_type type;
+ bool is_siginfo;
+ kernel_siginfo_t info;
+ int value;
};
static DEFINE_PER_CPU(struct send_signal_irq_work, send_signal_work);
@@ -811,7 +814,11 @@ static void do_bpf_send_signal(struct irq_work *entry)
struct send_signal_irq_work *work;
work = container_of(entry, struct send_signal_irq_work, irq_work);
- group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type);
+ if (work->is_siginfo)
+ group_send_sig_info(work->sig, &work->info, work->task, work->type);
+ else
+ group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type);
+
put_task_struct(work->task);
}
@@ -848,6 +855,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type)
* irq works get executed.
*/
work->task = get_task_struct(current);
+ work->is_siginfo = false;
work->sig = sig;
work->type = type;
irq_work_queue(&work->irq_work);
@@ -3484,3 +3492,71 @@ static int __init bpf_kprobe_multi_kfuncs_init(void)
}
late_initcall(bpf_kprobe_multi_kfuncs_init);
+
+__bpf_kfunc_start_defs();
+
+__bpf_kfunc int bpf_send_signal_remote(struct task_struct *task, int sig, enum pid_type type,
+ int value)
+{
+ struct send_signal_irq_work *work = NULL;
+ kernel_siginfo_t info;
+
+ if (type != PIDTYPE_PID && type != PIDTYPE_TGID)
+ return -EINVAL;
+ if (unlikely(task->flags & (PF_KTHREAD | PF_EXITING)))
+ return -EPERM;
+ if (unlikely(!nmi_uaccess_okay()))
+ return -EPERM;
+ /* Task should not be pid=1 to avoid kernel panic. */
+ if (unlikely(is_global_init(task)))
+ return -EPERM;
+
+ clear_siginfo(&info);
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_KERNEL;
+ info.si_pid = 0;
+ info.si_uid = 0;
+ info.si_value.sival_int = value;
+
+ if (irqs_disabled()) {
+ /* Do an early check on signal validity. Otherwise,
+ * the error is lost in deferred irq_work.
+ */
+ if (unlikely(!valid_signal(sig)))
+ return -EINVAL;
+
+ work = this_cpu_ptr(&send_signal_work);
+ if (irq_work_is_busy(&work->irq_work))
+ return -EBUSY;
+
+ work->task = get_task_struct(task);
+ work->is_siginfo = true;
+ work->info = info;
+ work->sig = sig;
+ work->type = type;
+ work->value = value;
+ irq_work_queue(&work->irq_work);
+ return 0;
+ }
+
+ return group_send_sig_info(sig, &info, task, type);
+}
+
+__bpf_kfunc_end_defs();
+
+BTF_KFUNCS_START(send_signal_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_send_signal_remote, KF_TRUSTED_ARGS)
+BTF_KFUNCS_END(send_signal_kfunc_ids)
+
+static const struct btf_kfunc_id_set bpf_send_signal_kfunc_set = {
+ .owner = THIS_MODULE,
+ .set = &send_signal_kfunc_ids,
+};
+
+static int __init bpf_send_signal_kfuncs_init(void)
+{
+ return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_send_signal_kfunc_set);
+}
+
+late_initcall(bpf_send_signal_kfuncs_init);
--
2.40.1
next prev parent reply other threads:[~2024-09-26 11:53 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-26 11:53 [PATCH bpf-next v2 0/2] Implement mechanism to signal other threads Puranjay Mohan
2024-09-26 11:53 ` Puranjay Mohan [this message]
2024-09-29 17:13 ` [PATCH bpf-next v2 1/2] bpf: implement bpf_send_signal_remote() kfunc Alexei Starovoitov
2024-09-30 21:48 ` Andrii Nakryiko
2024-09-30 21:52 ` Andrii Nakryiko
2024-10-01 8:39 ` Puranjay Mohan
2024-10-01 8:38 ` Puranjay Mohan
2024-09-26 11:53 ` [PATCH bpf-next v2 2/2] selftests/bpf: Augment send_signal test with remote signaling Puranjay Mohan
2024-09-29 17:17 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240926115328.105634-2-puranjay@kernel.org \
--to=puranjay@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=puranjay12@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox