Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loader: handle missing kfunc gracefully #1355

Closed
dylandreimerink opened this issue Feb 20, 2024 · 0 comments · Fixed by #1364
Closed

loader: handle missing kfunc gracefully #1355

dylandreimerink opened this issue Feb 20, 2024 · 0 comments · Fixed by #1364
Labels
enhancement New feature or request

Comments

@dylandreimerink
Copy link
Member

While looking at __weak support I came across the following pattern used in selftests:

void invalid_kfunc(void) __ksym __weak;

#define bpf_ksym_exists(sym) \
	({ \
		_Static_assert(!__builtin_constant_p(!!sym), #sym " should be marked as __weak"); \
		!!sym; \
	})

SEC("xdp") int xdp_prog(struct xdp_md *ctx) {
	if (bpf_ksym_exists(invalid_kfunc))
		invalid_kfunc();

	return 0;
}

So, essentially, this allows programs to handle cases where a given kfunc isn't available such as on older kernels or on kernels missing certain KCONFIG.

The __weak attribute is required for this to work so initially this results in a relocating instruction: asm relocation: invalid_kfunc: unsupported binding: STB_WEAK error. But assuming this is resolved by #466. We get the error: fixing up kfuncs: kfunc "invalid_kfunc": not supported.

The instructions for the example program are:

xdp_prog:
         ; if (bpf_ksym_exists(invalid_kfunc))
        0: LdImmDW dst: r1 imm: 0 <invalid_kfunc>
        2: JEqImm dst: r1 off: 1 imm: 0
         ; invalid_kfunc();
        3: Call Kfunc(-1) <invalid_kfunc>
         ; return 0;
        4: MovImm dst: r0 imm: 0
        5: Exit

The way libbpf handles this is by simply doing nothing. Since instruction 0 has a imm of 0 by default the code branch with the call is dead code and never trips the verifier.

There is a secondary issue, that being that we only relocate Call instructions, even if the kfunc were valid, instruction 0 would be ignored. So if we can fix both, we effectively allow CO-RE with kfuncs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant