Skip to content

Helper function bpf_probe_read_user_str

v5.5

Definition

Copyright (c) 2015 The Libbpf Authors. All rights reserved.

Copy a NULL terminated string from an unsafe user address unsafe_ptr to dst. The size should include the terminating NULL byte. In case the string length is smaller than size, the target is not padded with further NULL bytes. If the string length is larger than size, just size-1 bytes are copied and the last byte is set to NULL.

On success, returns the number of bytes that were written, including the terminal NULL. This makes this helper useful in tracing programs for reading strings, and more importantly to get its length at runtime. See the following snippet:

SEC("kprobe/sys_open")
void bpf_sys_open(struct pt_regs ctx) {
    char buf[PATHLEN]; // PATHLEN is defined to 256
    int res = bpf_probe_read_user_str(buf, sizeof(buf), ctx->di);
    // Consume buf, for example push it to
    // userspace via bpf_perf_event_output(); we
    // can use res (the string length) as event
    // size, after checking its boundaries.
}

In comparison, using bpf_probe_read_user() helper here instead to read the string would require to estimate the length at compile time, and would often result in copying more memory than necessary.

Another useful use case is when parsing individual process arguments or individual environment variables navigating current->mm->arg_start and current->mm->env_start: using this helper and the return value, one can quickly iterate at the right offset of the memory area.

Returns

On success, the strictly positive length of the output string, including the trailing NULL character. On error, a negative value.

static long (* const bpf_probe_read_user_str)(void *dst, __u32 size, const void *unsafe_ptr) = (void *) 114;

Usage

When using bpf_probe_read_user_str, it is important to ensure that the buffer size (size) includes space for the NULL terminator to prevent reading unintended memory. If the user-space string is larger than the buffer, the function truncates it to size - 1 bytes and forces a NULL terminator. Always check the return value, as a negative value indicates failure, while a positive value represents the number of bytes copied, including the NULL terminator. This function should not be used if the string resides in kernel memory; in such cases, bpf_probe_read_kernel_str is the correct alternative.

Program types

This helper call can be used in the following program types:

Example

SEC("tracepoint/syscalls/sys_enter_openat")
int trace_openat(struct trace_event_raw_sys_enter *ctx) {
    char filename[256];
    const char *user_filename = (const char *)ctx->args[1];

    int ret = bpf_probe_read_user_str(filename, sizeof(filename), user_filename);
    if (ret > 0) {
        bpf_printk("Process opened file: %s\n", filename);
    } else {
        bpf_printk("Failed to read filename, error: %d\n", ret);
    }

    return 0;
}