Helper function bpf_probe_write_user
Definition
Copyright (c) 2015 The Libbpf Authors. All rights reserved.
Attempt in a safe way to write len bytes from the buffer src to dst in memory. It only works for threads that are in user context, and dst must be a valid user space address.
This helper should not be used to implement any kind of security mechanism because of TOC-TOU attacks, but rather to debug, divert, and manipulate execution of semi-cooperative processes.
Keep in mind that this feature is meant for experiments, and it has a risk of crashing the system and running programs. Therefore, when an eBPF program using this helper is attached, a warning including PID and process name is printed to kernel logs.
Returns
0 on success, or a negative error in case of failure.
static long (* const bpf_probe_write_user)(void *dst, const void *src, __u32 len) = (void *) 36;
Usage
Docs could be improved
This part of the docs is incomplete, contributions are very welcome
Program types
This helper call can be used in the following program types:
BPF_PROG_TYPE_KPROBE
BPF_PROG_TYPE_LSM
BPF_PROG_TYPE_PERF_EVENT
BPF_PROG_TYPE_RAW_TRACEPOINT
BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
BPF_PROG_TYPE_SYSCALL
BPF_PROG_TYPE_TRACEPOINT
BPF_PROG_TYPE_TRACING
Example
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
// We do it in the exit to not alter the syscall behavior. The userspace program
// will see the new filename only after the syscall execution.
SEC("fexit/__x64_sys_open")
int BPF_PROG(p_open, struct pt_regs *regs, long ret) {
// If it is our example program overwrite the open path.
struct task_struct *task = (struct task_struct *)bpf_get_current_task_btf();
if (bpf_strncmp(task->comm, TASK_COMM_LEN, "example") != 0) {
return 0;
}
// SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
// first param is the pointer to filename.
void *filename_ptr = (void *)PT_REGS_PARM1_CORE_SYSCALL(regs);
const char filename[16] = "/tmp/new";
if (bpf_probe_write_user(filename_ptr, filename, 16)) {
bpf_printk("Failed to write new filename\n");
}
return 0;
}