-
Notifications
You must be signed in to change notification settings - Fork 26
Fix jump calculation #36
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
base: master
Are you sure you want to change the base?
Conversation
Currently, an error is triggered when calling ToEBPF() on cBPF
instructions generated by the filter "ip6 protochain 58":
$ tcpdump -dd ip6 protochain 58 | cat -n
Warning: assuming Ethernet
1 { 0x28, 0, 0, 0x0000000c },
2 { 0x15, 0, 33, 0x000086dd },
3 { 0x30, 0, 0, 0x00000014 },
4 { 0x1, 0, 0, 0x00000028 },
5 { 0x15, 27, 0, 0x0000003a },
6 { 0x15, 26, 0, 0x0000003b },
7 { 0x15, 3, 0, 0x00000000 },
8 { 0x15, 2, 0, 0x0000003c },
9 { 0x15, 1, 0, 0x0000002b },
10 { 0x15, 0, 9, 0x0000002c },
11 { 0x50, 0, 0, 0x0000000e },
12 { 0x2, 0, 0, 0x00000000 },
13 { 0x50, 0, 0, 0x0000000f },
14 { 0x4, 0, 0, 0x00000001 },
15 { 0x24, 0, 0, 0x00000008 },
16 { 0xc, 0, 0, 0x00000000 },
17 { 0x7, 0, 0, 0x00000000 },
18 { 0x60, 0, 0, 0x00000000 },
19 { 0x5, 0, 0, 0xfffffff1 },
20 { 0x15, 0, 12, 0x00000033 },
21 { 0x87, 0, 0, 0x00000000 },
22 { 0x50, 0, 0, 0x0000000e },
23 { 0x2, 0, 0, 0x00000000 },
24 { 0x87, 0, 0, 0x00000000 },
25 { 0x4, 0, 0, 0x00000001 },
26 { 0x7, 0, 0, 0x00000000 },
27 { 0x50, 0, 0, 0x0000000e },
28 { 0x4, 0, 0, 0x00000002 },
29 { 0x24, 0, 0, 0x00000004 },
30 { 0x7, 0, 0, 0x00000000 },
31 { 0x60, 0, 0, 0x00000000 },
32 { 0x5, 0, 0, 0xffffffe4 },
33 { 0x4, 0, 0, 0x00000000 },
34 { 0x15, 0, 1, 0x0000003a },
35 { 0x6, 0, 0, 0x00040000 },
36 { 0x6, 0, 0, 0x00000000 },
Line 19 {0x5, 0, 0, 0xfffffff1} is a "JA 0xfffffff1" instruction. When
cbpfc.ToEBPF() attempts to translate this jump, it miscalculates the
destination due to the incorrect type of the pos variable.
The bug arises because pos is currently of type uint (which is uint64 on
64-bit systems), whereas it should be uint32 to correctly emulate cBPF's
32-bit overflow semantics. Instead of computing the correct jump
destination as:
uint32(18 + 1 + 0xfffffff1) = 4
It evaluates to:
18 + 1 + 0xfffffff1 = 0x100000004 (due to 64-bit addition)
As a result, the jump target becomes invalid, and ToEBPF() errors out with:
instruction 18: ja 4294967281 flows past last instruction
This patch changes the type of pos to uint32, ensuring correct overflow
behavior and jump target computation consistent with cBPF expectations.
Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
|
Great catch, thank you for the PR! Do you mind adding a test? I think we can add one in |
|
Hey Arthur, could you help me with the test please, I am afraid I am off keyboard for a few days 🙏 |
|
One more thing that I’m sure you’re already aware of: this PR does not fix cloudflare/cbpfc#37, because our cbpf.CompileEBPF() still gets stuck in an infinite loop due to the backwards jump. |
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
There is a known issue that cloudfare/cbpfc can't properly handle "jump back" cBPF: cloudflare/cbpfc#36. Unfortunately, "protochain" pcap filter often generates such "jump back" instructions, leading to errors like: unable to compute blocks: instruction 18: ja 4294967281 flows past last instruction This patch disables protochain when compiling libpcap, so users receive a clearer error: $ pwru ip6 protochain 58 2025/05/23 22:42:53 Failed to inject filter ebpf for kprobe_multi_skb_5: failed to pcap_compile 'ip6 protochain 58': protochain not supported (l3=false) Signed-off-by: gray <greyschwinger@gmail.com>
Currently, an error is triggered when calling ToEBPF() on cBPF instructions generated by the filter "ip6 protochain 58":
Line 19 {0x5, 0, 0, 0xfffffff1} is a "JA 0xfffffff1" instruction. When cbpfc.ToEBPF() attempts to translate this jump, it miscalculates the destination due to the incorrect type of the pos variable.
The bug arises because pos is currently of type uint (which is uint64 on 64-bit systems), whereas it should be uint32 to correctly emulate cBPF's 32-bit overflow semantics. Instead of computing the correct jump destination as:
It evaluates to:
As a result, the jump target becomes invalid, and ToEBPF() errors out with:
This patch changes the type of pos to uint32, ensuring correct overflow behavior and jump target computation consistent with cBPF expectations.