Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> writes: > On Tue, Oct 8, 2024 at 4:49 AM Puranjay Mohan <puranjay@xxxxxxxxxx> wrote: >> >> Implement bpf_send_signal_task 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@xxxxxxxxxx> >> --- >> kernel/bpf/helpers.c | 1 + >> kernel/trace/bpf_trace.c | 52 +++++++++++++++++++++++++++++++++------- >> 2 files changed, 45 insertions(+), 8 deletions(-) >> >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >> index 4053f279ed4cc..2fd3feefb9d94 100644 >> --- a/kernel/bpf/helpers.c >> +++ b/kernel/bpf/helpers.c >> @@ -3035,6 +3035,7 @@ BTF_ID_FLAGS(func, bpf_task_get_cgroup1, KF_ACQUIRE | KF_RCU | KF_RET_NULL) >> #endif >> BTF_ID_FLAGS(func, bpf_task_from_pid, KF_ACQUIRE | KF_RET_NULL) >> BTF_ID_FLAGS(func, bpf_throw) >> +BTF_ID_FLAGS(func, bpf_send_signal_task, KF_TRUSTED_ARGS) >> BTF_KFUNCS_END(generic_btf_ids) >> >> static const struct btf_kfunc_id_set generic_kfunc_set = { >> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c >> index a582cd25ca876..d9662e84510d3 100644 >> --- a/kernel/trace/bpf_trace.c >> +++ b/kernel/trace/bpf_trace.c >> @@ -802,6 +802,8 @@ struct send_signal_irq_work { >> struct task_struct *task; >> u32 sig; >> enum pid_type type; >> + bool has_siginfo; >> + struct kernel_siginfo info; >> }; >> >> static DEFINE_PER_CPU(struct send_signal_irq_work, send_signal_work); >> @@ -809,27 +811,46 @@ static DEFINE_PER_CPU(struct send_signal_irq_work, send_signal_work); >> static void do_bpf_send_signal(struct irq_work *entry) >> { >> struct send_signal_irq_work *work; >> + struct kernel_siginfo *siginfo; >> >> work = container_of(entry, struct send_signal_irq_work, irq_work); >> - group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type); >> + siginfo = work->has_siginfo ? &work->info : SEND_SIG_PRIV; >> + >> + group_send_sig_info(work->sig, siginfo, work->task, work->type); >> put_task_struct(work->task); >> } >> >> -static int bpf_send_signal_common(u32 sig, enum pid_type type) >> +static int bpf_send_signal_common(u32 sig, enum pid_type type, struct task_struct *task, u64 value) >> { >> struct send_signal_irq_work *work = NULL; >> + struct kernel_siginfo info; >> + struct kernel_siginfo *siginfo; >> + >> + if (!task) { >> + task = current; >> + siginfo = SEND_SIG_PRIV; >> + } else { >> + 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_ptr = (void *)(unsigned long)value; >> + siginfo = &info; >> + } >> >> /* Similar to bpf_probe_write_user, task needs to be >> * in a sound condition and kernel memory access be >> * permitted in order to send signal to the current >> * task. >> */ >> - if (unlikely(current->flags & (PF_KTHREAD | PF_EXITING))) >> + 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(current))) >> + if (unlikely(is_global_init(task))) >> return -EPERM; >> >> if (irqs_disabled()) { >> @@ -847,19 +868,21 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) >> * to the irq_work. The current task may change when queued >> * irq works get executed. >> */ >> - work->task = get_task_struct(current); >> + work->task = get_task_struct(task); >> + work->has_siginfo = siginfo == &info; >> + copy_siginfo(&work->info, &info); > > we shouldn't copy_siginfo() if !work->has_siginfo, no? Yes, but it is only used when has_siginfo is true, so copying it doesn't cause any problems. I just didn't want to add another check here. > other than that, lgtm > > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> Thanks for the Ack. I hope this can go in now! Thanks, Puranjay Mohan
Attachment:
signature.asc
Description: PGP signature