On 2024-10-23 04:12, Andrii Nakryiko wrote:
On Tue, Oct 22, 2024 at 7:14 AM Levi Zim <rsworktech@xxxxxxxxxxx> wrote:
Hi,
I have a question about how use bpf dynptr and bpf_probe_read_kernel
together.
Assuming we have an fexit program attached to pty_write(static ssize_t
pty_write(struct tty_struct *tty, const u8 *buf, size_t c))
I want to send some metadata and the written bytes to the pty to user
space via a BPF RingBuf.
While I could reserve a statistically known amount of memory on ringbuf,
it is a waste of the ringbuf's space if there are only one or two bytes
written to pty.
So instead I tried to use bpf_ringbuf_reserve_dynptr to dynamically
reserve the memory on the ringbuf and it works great,
until when I want to use bpf_dynptr_write to read the kernel memory at
buf into the memory managed by dynptr:
78: (85) call bpf_dynptr_write#202
R3 type=scalar expected=fp, pkt, pkt_meta, map_key, map_value,
mem, ringbuf_mem, buf, trusted_ptr_
The verifier appears to be rejecting using bpf_dynptr_write in a way
similar to bpf_probe_read_kernel.
Is there any way to achieve this without reading the data into an
intermediate buffer?
Yes, you can bpf_probe_read_kernel() into dynptr's memory chunk by
chunk. I recently wrote an example of doing chunk-by-chunk copying of
XDP data into ringbuf dynptr, you can find it at [0].
[0] https://github.com/libbpf/libbpf-bootstrap/commit/046fad60df3e39540937b5ec6ee86054f33d3f28
Thanks! That's really helpful.
Or could we remove this limitation in the verifier at least for tracing
programs that are already capable of
calling bpf_probe_read_kernel to read arbitrary kernel memory?
This would have to be a new special API, basically a dynptr version of
bpf_probe_read_kernel, something like:
int bpf_probe_read_kernel_dynptr(struct bpf_dynptr *dst, u32 offset,
u32 size, void *untrusted_ptr);
We can probably add that, which seems like a straightforward addition
to me. We'd probably want bpf_probe_read_user_dynptr() and
bpf_copy_from_user_dynptr() to go in a single consistent batch.
Implementation wise it's a super think wrapper around existing
functionality (we are just avoiding fixed buffer size restrictions of
existing probe/copy_from APIs)
Thoughts?
Probably someone might also want bpf_probe_read_{kernel,user}_str_dynptr
in the future.
Best regards,
Levi