Skip to content

fix: ensure eBPF verifier compliance by adding explicit fallback returns after tail calls#16

Open
SiyuanSun0736 wants to merge 1 commit intomultikernel:mainfrom
SiyuanSun0736:fix_tail_call
Open

fix: ensure eBPF verifier compliance by adding explicit fallback returns after tail calls#16
SiyuanSun0736 wants to merge 1 commit intomultikernel:mainfrom
SiyuanSun0736:fix_tail_call

Conversation

@SiyuanSun0736
Copy link
Contributor

Problem Definition
The bpf_tail_call() helper in eBPF is not guaranteed to succeed. If the call fails (e.g., due to an invalid index or exceeding the call stack limit), execution continues at the instruction immediately following the call site. The eBPF verifier requires that every code path reaches a definitive termination point. Without an explicit return after a tail call, the verifier may reject the program as it cannot guarantee all paths exit.

Mechanism of Change
A new helper function get_tail_call_fallback_return has been implemented to determine the correct return value based on the program's execution context. This ensures that the generated C code includes a fallback return statement immediately following every bpf_tail_call.

Context Mapping Logic
The return value is determined by the current_function_context_type variable:

Context Type (Some string) Fallback Return Value
"xdp" XDP_PASS
"tc" TC_ACT_OK
None / Other 0

Technical Breakdown

  1. Code Generation: The logic modifies the emission of IRReturnTailCall and IRReturnCall.
  2. Instrumentation: Adds a C comment /* tail call fallback */ to the emitted return statement for traceability and debugging.
  3. Instruction Support:
    • IRReturnTailCall: Explicit tail calls with specific indices.
    • IRReturnCall: Generic calls mapped to tail call index 0.
    • Match Arms: Coverage for both IRConstantPattern and IRDefaultPattern within IRMatchReturn instructions.

Verification Results

The implementation is verified via the following OCaml unit tests:

  • test_tail_call_fallback_constant_arm_xdp: Confirms that in an XDP context, a constant match arm containing a tail call generates return XDP_PASS;.
  • test_tail_call_fallback_default_arm_tc: Confirms that in a TC context, a default match arm generates return TC_ACT_OK;.
  • test_return_call_fallback_generic_context: Confirms that when the context is undefined, the generator defaults to return 0; and correctly handles implicit tail calls (index 0).

…l paths have an explicit return in the event that `bpf_tail_call()` fails.

Add relevant tests.
Copilot AI review requested due to automatic review settings March 19, 2026 11:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the eBPF C code generator to satisfy verifier requirements by emitting an explicit fallback return immediately after any bpf_tail_call() emitted from IRMatchReturn arms, ensuring all control-flow paths terminate even if the tail call fails at runtime.

Changes:

  • Added get_tail_call_fallback_return to map the current function context (xdp/tc/other) to an appropriate return constant (XDP_PASS / TC_ACT_OK / 0).
  • Updated IRMatchReturn codegen for both constant and default arms so IRReturnCall and IRReturnTailCall emit return <fallback>; /* tail call fallback */ after bpf_tail_call(...).
  • Added unit tests covering XDP, TC, and generic contexts, and verifying the legacy “continue execution” comment is no longer emitted for these return-position tail calls.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/ebpf_c_codegen.ml Adds context-aware fallback return selection and emits explicit fallback returns after tail calls within IRMatchReturn arms.
tests/test_ebpf_c_codegen.ml Adds regression tests validating tail call fallback return emission across XDP/TC/generic contexts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants