Program type BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
Raw tracepoint writable programs are similar to raw tracepoint programs, but they allow you to write to the given context.
Usage
This program type can be attached to tracepoints that were placed at specific locations in the kernel by the kernel developers. Unlike non-writable tracepoints, these ones can write to the whole context or parts of the context. This essentially allows you to modify the kernel's behavior at runtime in a very specific way.
Writable raw tracepoint programs can only be attached to tracepoints which have been created with the DEFINE_EVENT_WRITABLE
or DECLARE_TRACE_WRITABLE
macros.
In practice there are very limited of such tracepoints, on only one as of kernel v6.14 is nbd_send_request
Context
The context to this program type is an array of u64
values. Each element representing an argument of the tracepoint. The program has to cast the elements to their proper type, libbpf provides the BPF_PROG
macro to help with this.
The first element of the context is referred to as the "writable buffer", it will be a pointer to a values which is allowed to be modified. The verifier will check that you do not attempt to modify any other parts or modify outside of the bounds of the writable buffer.
Attachment
Raw tracepoints can be attached in two ways, first is with a dedicated syscall, the second method is with the more generic BPF link syscall.
Syscall
The dedicated syscall BPF_RAW_TRACEPOINT_OPEN
can be used to attach the raw tracepoint. This requires the name
field to be set to a string containing the name of the tracepoint to which the user whishes to attach to. The prog_fd
attribute field should be set to the file descriptor of the BPF program to attach.
Docs could be improved
This part of the docs is incomplete, contributions are very welcome
Example
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */
SEC("raw_tp.w/bpf_testmod_test_writable_bare")
int BPF_PROG(handle_raw_tp_writable_bare,
struct bpf_testmod_test_writable_ctx *writable)
{
raw_tp_writable_bare_in_val = writable->val;
writable->early_ret = raw_tp_writable_bare_early_ret;
writable->val = raw_tp_writable_bare_out_val;
return 0;
}
Helper functions
Not all helper functions are available in all program types. These are the helper calls available for raw tracepoint writable programs:
Supported helper functions
bpf_cgrp_storage_delete
bpf_cgrp_storage_get
bpf_copy_from_user
bpf_copy_from_user_task
bpf_current_task_under_cgroup
bpf_dynptr_data
bpf_dynptr_from_mem
bpf_dynptr_read
bpf_dynptr_write
bpf_find_vma
bpf_for_each_map_elem
bpf_get_branch_snapshot
bpf_get_current_ancestor_cgroup_id
bpf_get_current_cgroup_id
bpf_get_current_comm
bpf_get_current_pid_tgid
bpf_get_current_task
bpf_get_current_task_btf
bpf_get_current_uid_gid
bpf_get_func_ip
bpf_get_ns_current_pid_tgid
bpf_get_numa_node_id
bpf_get_prandom_u32
bpf_get_smp_processor_id
bpf_get_stack
bpf_get_stackid
bpf_get_task_stack
bpf_jiffies64
bpf_kptr_xchg
bpf_ktime_get_boot_ns
bpf_ktime_get_ns
bpf_ktime_get_tai_ns
bpf_loop
bpf_map_delete_elem
bpf_map_lookup_elem
bpf_map_lookup_percpu_elem
bpf_map_peek_elem
bpf_map_pop_elem
bpf_map_push_elem
bpf_map_update_elem
bpf_per_cpu_ptr
bpf_perf_event_output
bpf_perf_event_read
bpf_perf_event_read_value
bpf_probe_read
bpf_probe_read_kernel
bpf_probe_read_kernel_str
bpf_probe_read_str
bpf_probe_read_user
bpf_probe_read_user_str
bpf_probe_write_user
bpf_ringbuf_discard
bpf_ringbuf_discard_dynptr
bpf_ringbuf_output
bpf_ringbuf_query
bpf_ringbuf_reserve
bpf_ringbuf_reserve_dynptr
bpf_ringbuf_submit
bpf_ringbuf_submit_dynptr
bpf_send_signal
bpf_send_signal_thread
bpf_snprintf
bpf_snprintf_btf
bpf_spin_lock
bpf_spin_unlock
bpf_strncmp
bpf_tail_call
bpf_task_pt_regs
bpf_task_storage_delete
bpf_task_storage_get
bpf_this_cpu_ptr
bpf_timer_cancel
bpf_timer_init
bpf_timer_set_callback
bpf_timer_start
bpf_trace_printk
bpf_trace_vprintk
bpf_user_ringbuf_drain
KFuncs
There are currently no kfuncs supported for this program type