Closed
Description
bpftool prog dump
seems to give wrong callq
address.
First let's Inspect a bpf prog with bpf_redirect
call
$ s bpftool p s tag 71cf8deecfc1bb77
1125: sched_cls name tail_ipv4_policy tag 71cf8deecfc1bb77 gpl
loaded_at 2023-07-11T11:08:05+0800 uid 0
xlated 9696B jited 5594B memlock 12288B map_ids 223,118,140,128,222,182,127,114,115,116,143,145
btf_id 662
$ s bpftool p d j tag 71cf8deecfc1bb77 | grep 'redirect(' -A3
; return redirect(ifindex, flags);
15a1: xorl %esi, %esi
15a3: movq -192(%rbp), %rax
15aa: callq 0xffffffffc377aedc
As we see the callq address is 0xffffffffc377aedc
.
However that seems to be wrong, because ksym says bpf_redirect
is at ffffffff85649ef0
$ s cat /proc/kallsyms | awk '$2 ~ /T/ && /bpf_redirect$/'
ffffffff85649ef0 T bpf_redirect
Let's check the opcode using bpftool p d j tag 71cf8deecfc1bb77 opcode
:
$ s bpftool p d j tag 71cf8deecfc1bb77 opcode | grep 'redirect(' -A6
; return redirect(ifindex, flags);
15a1: xorl %esi, %esi
31 f6
15a3: movq -192(%rbp), %rax
48 8b 85 40 ff ff ff
15aa: callq 0xffffffffc377aedc
e8 2d 99 77 c3
The opcode is e8 2d 99 77 c3
, it can be explained as:
e8
is x64's offset-relative call.- offset is
2d 99 77 c3
in little endian, which is0xc377992d
in hex, or,0xc377992d - (1<<32)
=-0x3c8866d3
in 2's complement. - so the target address should be
addressof(this_bpf_prog) + 0x15aa + 5 - 0x3c8866d3
As addressof(this_bpf_prog)
can be found in ksym:
$ s cat /proc/kallsyms | grep 71cf8deecfc1bb77
ffffffffc1ecf014 t bpf_prog_71cf8deecfc1bb77_tail_ipv4_policy [bpf]
We finally calculate the call address: 0xffffffffc1ecf014 + 0x15aa + 5 - 0x3c8866d3
= 0xffffffff85649ef0
, which is exactly the bpf_redirect address showed in the ksym.
Therefore, I suspect bpftool calculates the wrong callq address.