Skip to content

Helper function bpf_probe_write_user

v4.8

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:

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;
}