Re: [PATCH bpf-next] libbpf: support weak typed ksyms.
From: Andrii Nakryiko <hidden>
Date: 2021-08-06 22:40:33
Also in:
bpf
On Mon, Aug 2, 2021 at 2:29 PM Hao Luo [off-list ref] wrote:
Currently weak typeless ksyms have default value zero, when they don't exist in the kernel. However, weak typed ksyms are rejected by libbpf. This means that if a bpf object contains the declaration of a non-existing weak typed ksym, it will be rejected even if there is no program that references the symbol. In fact, we could let them to pass the checks in libbpf and leave the object to be rejected by the bpf verifier. More specifically, upon seeing a weak typed symbol, libbpf can assign it a zero btf_id, which is associated to the type 'void'. The verifier expects the symbol to be BTF_VAR_KIND instead, therefore will reject loading. In practice, we often add new kernel symbols and roll out the kernel changes to fleet. And we want to release a single bpf object that can be loaded on both the new and the old kernels. Passing weak typed ksyms in libbpf allows us to do so as long as the programs that reference the new symbols are disabled on the old kernel.
How do you detect whether a given ksym is present or not? You check
that from user-space and then use .rodata to turn off pieces of BPF
logic? That's quite inconvenient. It would be great if these typed
ksyms worked the same way as typeless ones:
extern const int bpf_link_fops3 __ksym __weak;
/* then in BPF program */
if (&bpf_link_fops3) {
/* use bpf_link_fops3 */
}
I haven't tried, but I suspect it could be made to work if libbpf
replaces corresponding ldimm64 instruction (with BTF ID) into a plain
ldimm64 instruction loading 0 directly. That would allow the above
check (and it would be known false to the verifier) to succeed without
the verifier rejecting the BPF program. If actual use of non-existing
typed symbol is not guarded properly, verifier would see that register
is not PTR_TO_BTF_ID and wouldn't allow to use it for direct memory
reads or passing it to BPF helpers.
Have you considered such an approach?
Separately, please use ASSERT_XXX() macros for tests, not plain
CHECK()s. Thanks.
Signed-off-by: Hao Luo <redacted> --- tools/lib/bpf/libbpf.c | 17 +++++- .../selftests/bpf/prog_tests/ksyms_btf.c | 42 +++++++++++++ .../selftests/bpf/progs/test_ksyms_weak.c | 60 +++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_ksyms_weak.c
[...]