aya icon indicating copy to clipboard operation
aya copied to clipboard

Allow to load programs with ksyms

Open vadorovsky opened this issue 8 months ago • 8 comments

Currently, loading a program which contains ksyms, like:

void bpf_rcu_read_lock(void) __ksym;
void bpf_rcu_read_unlock(void) __ksym;

Fails with the following error:

thread 'tests::task_storage::test_task_storage_get' panicked at test/integration-test/src/tests/task_storage.rs:8:52:
called `Result::unwrap()` on an `Err` value: BtfError(UnknownSectionSize { section_name: ".ksyms" })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This issue is a blocker in shipping the task storage:

  • #203
  • #1161

The integration test, proving that it works, needs RCU locking here:

https://github.com/vadorovsky/aya/blob/1f2b881c9658895c04f3690f523184ea29b686bb/test/integration-test/bpf/task_storage.bpf.c#L24-L35

And the only option for RCU locking is using ksyms.

vadorovsky avatar Apr 07 '25 10:04 vadorovsky

To be precise, this logic needs to be replicated

https://elixir.bootlin.com/linux/v6.14.4/source/tools/lib/bpf/libbpf.c#L4171

vadorovsky avatar Apr 28 '25 03:04 vadorovsky

Notes (for myself)

WIP branch https://github.com/vadorovsky/aya/tree/ksym

The verifier error that appears when loading a program with ksym with Aya is

called `Result::unwrap()` on an `Err` value: BtfError(LoadError { io_error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }, verifier_log: magic: 0xeb9f
version: 1
flags: 0x0
hdr_len: 24
type_off: 0
type_len: 18308
str_off: 18308
str_len: 12483
btf_total_size: 30815
[1] PTR (anon) type_id=3
[2] INT int size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[3] ARRAY (anon) type_id=2 index_type_id=4 nr_elems=29
[4] INT __ARRAY_SIZE_TYPE__ size=4 bits_offset=0 nr_bits=32 encoding=(none)
[5] PTR (anon) type_id=6
[6] ARRAY (anon) type_id=2 index_type_id=4 nr_elems=1
[7] PTR (anon) type_id=2
[8] PTR (anon) type_id=9
[9] TYPEDEF __u32 type_id=10
[10] INT unsigned int size=4 bits_offset=0 nr_bits=32 encoding=(none)
[11] STRUCT (anon) size=32 vlen=4
        type type_id=1 bits_offset=0
        map_flags type_id=5 bits_offset=64
        key type_id=7 bits_offset=128
        value type_id=8 bits_offset=192
[12] VAR task_storage type_id=11 linkage=1
[13] PTR (anon) type_id=14
[14] INT unsigned long long size=8 bits_offset=0 nr_bits=64 encoding=(none)
[15] FUNC_PROTO (anon) return=2 args=(13 ctx)
[16] FUNC sys_enter type_id=15
[17] FUNC_PROTO (anon) return=0 args=(void)
[18] FUNC bpf_rcu_read_lock type_id=17 Invalid func linkage
 })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

libbpf is doing the following fixup which I'm trying to replicate - it puts the correct BTF ID of the function, retrieved from kernel's BTF, into program's BTF node (in the example above, it would be [18]).

https://elixir.bootlin.com/linux/v6.14.4/source/tools/lib/bpf/libbpf.c#L8366

https://elixir.bootlin.com/linux/v6.14.4/source/tools/lib/bpf/libbpf.c#L4328

libbpf commit introducing the fixups: https://github.com/torvalds/linux/commit/5bd022ec01f06

vadorovsky avatar Apr 28 '25 11:04 vadorovsky

Moved to "Todo" - I'm going to get back to it once the new Linux incidents are done.

vadorovsky avatar May 19 '25 11:05 vadorovsky

Please update the date, status and iteration of this issue

scamnasio avatar May 26 '25 14:05 scamnasio

Resuming work on this now.

So far I still didn't get it fully working. My port of the relocation part (libbpf code https://github.com/torvalds/linux/commit/5bd022ec01f06#diff-333e3796217dda054b006e3cfe59f542121cf8a07f67f21c6ab7851ecf0c02e1R3162-R3197) still doesn't result in loadable program, I need to investigate what I did wrong.

vadorovsky avatar Jun 09 '25 10:06 vadorovsky

Tried to start working on this. I notice that the current implementation does not perform relocations for external functions, but I'm not sure how to implement this ergonomically.

addisoncrump avatar Aug 12 '25 09:08 addisoncrump

Do let me know how I can help with this... Unfortunately, this is currently blocking an upgrade for me, so I'd like to help resolve this. 🙂

addisoncrump avatar Aug 12 '25 15:08 addisoncrump

Do let me know how I can help with this... Unfortunately, this is currently blocking an upgrade for me, so I'd like to help resolve this. 🙂

Same here. Updating our project to Rust 1.91 also requires us to bump the nightly we are using to compile our eBPF code and with a more recent nightly, we are hitting this.

Happy to help with this.

thomaseizinger avatar Nov 02 '25 22:11 thomaseizinger