Re: How to combine bpf dynptr and bpf_probe_read_kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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






[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux