Skip to content

KFunc bpf_send_signal_task

v6.13

This function allows for the sending of signals to threads and processes.

Definition

bpf_send_signal_task is a kfunc that is similar to the 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.

Parameters

task: Pointer to the task_struct of the thread or process to send the signal to.

sig: Signal number to send.

type: Specifies to send the signal to a specific process or a thread. Possible values: PIDTYPE_PID(0) and PIDTYPE_TGID(1)

value: Cookie to send with the signal.

Returns

0 on success, a negative error code on failure

Signature

int bpf_send_signal_task(struct task_struct *task, int sig, pid_type type, u64 value)

Usage

Docs could be improved

This part of the docs is incomplete, contributions are very welcome

Program types

The following program types can make use of this kfunc:

Example

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Facebook
#include <vmlinux.h>
#include <linux/version.h>
#include <bpf/bpf_helpers.h>

struct task_struct *bpf_task_from_pid(int pid) __ksym;
void bpf_task_release(struct task_struct *p) __ksym;
int bpf_send_signal_task(struct task_struct *task, int sig, enum pid_type type, u64 value) __ksym;

__u32 sig = 0, pid = 0, status = 0, signal_thread = 0, target_pid = 0;

static __always_inline int bpf_send_signal_test(void *ctx)
{
    struct task_struct *target_task = NULL;
    int ret;
    u64 value;

    if (status != 0 || pid == 0)
        return 0;

    if ((bpf_get_current_pid_tgid() >> 32) == pid) {
        if (target_pid) {
            target_task = bpf_task_from_pid(target_pid);
            if (!target_task)
                return 0;
            value = 8;
        }

        if (signal_thread) {
            if (target_pid)
                ret = bpf_send_signal_task(target_task, sig, PIDTYPE_PID, value);
            else
                ret = bpf_send_signal_thread(sig);
        } else {
            if (target_pid)
                ret = bpf_send_signal_task(target_task, sig, PIDTYPE_TGID, value);
            else
                ret = bpf_send_signal(sig);
        }
        if (ret == 0)
            status = 1;
    }

    if (target_task)
        bpf_task_release(target_task);

    return 0;
}