*
Hi all,
**
I’d like to discuss supporting dynamic pointers (“bpf_dynptr”) in bpf. A
dynamic pointer is a pointer that embeds extra metadata alongside the
address - this abstraction will allow bpf programs to interact with
memory dynamically in a safe way. The verifier and bpf helper functions
can use the metadata stored in the dynamic pointer to enforce safety
guarantees.
Some useful applications of dynamic pointers include
* Dynamically-sized ringbuf reservations
Currently, our only way of writing dynamically-sized data into a ring
buffer is through bpf_ringbuf_output, but this incurs an extra memcpy
cost. bpf_ringbuf_reserve + bpf_ringbuf_commit avoids this extra memcpy,
but it can only safely support reservation sizes that are
statically-known since the verifier cannot guarantee that the bpf
program won’t access memory outside the reserved space. bpf_dynptrs will
enable dynamically-sized ring buffer reservations without the extra memcpy.
* Dynamic memory allocations
Bpf programs currently do not support dynamic memory allocations, but
with the dynptr abstraction, the verifier can enforce that any memory
dynamically allocated will always be freed. One useful extension of this
is persisting dynamic memory allocations in a map to share between programs.
* Dynamically parsing packet data
Currently when we parse network packet data (eg xdp_md->data,
sk_buff->data) in a bpf program, there are two main inconveniences:
1.
We can only iterate through the packet data in statically-known sizes
2.
The verifier requires manual checks in the bpf program code to
ensure we are not accessing any memory beyond the end of the packet
data. Some of these checks can be broken by clang when it does
clever optimizations.
The bpf_dynptr abstraction handles both these cases. By embedding the
packet data behind a bpf_dynptr, the helper functions used to read/write
to the data* can check that no memory violations occur.*
*