Skip to content

wrong bpf call offset when dumping xlated instructions #1695

Open
@xixiliguo

Description

@xixiliguo

Describe the bug

If prog was jited after loading, PC offset of bpf pseudo call was stored at field off, not imm.
please see below code for details
https://github.com/torvalds/linux/blob/87a132e73910e8689902aed7f2fc229d6908383b/kernel/bpf/verifier.c#L20783-L20795

currenct logic does not distinguish whether instructions was jited or not, just use imm as call offset .

How to reproduce

For xlated dump of same bpf c code , epbf-go show pc+1, but bpftool show pc+2

#include "bpf_endian.h"
#include "common.h"

char __license[] SEC("license") = "Dual MIT/GPL";


static __noinline int test(int i) {
	return i + 1;
}

int g = 1;

SEC("kprobe/hello")
int hello(struct pt_regs *ctx) {
	int m = test(g);
	return m + g;
}
func main() {
	objs := bpfObjects{}
	loadBpfObjects(&objs, nil)
	defer objs.Close()
	info, _ := objs.Hello.Info()
	ins, _ := info.Instructions()
	fmt.Printf("%+v\n", ins)
}

The output is as follows:

hello:
          ; int m = test(g);
         0: LoadMapValue dst: r1, fd: 274 off: 0
          ; int m = test(g);
         2: LdXMemW dst: r6 src: r1 off: 0 imm: 0
         3: MovReg dst: r1 src: r6
         4: Call 1                                                          // it's worng compared with bpftool 
          ; return m + g;
         5: AddReg dst: r0 src: r6
          ; return m + g;
         6: Exit
          ; static __noinline int test(int i) {
         7: MovReg dst: r0 src: r1
          ; return i + 1;
         8: AddImm dst: r0 imm: 1
          ; return i + 1;
         9: Exi
# bpftool prog load bpf_bpfel.o /sys/fs/bpf/test && bpftool prog dump xlated name hello opcodes
int hello(struct pt_regs * ctx):
; int m = test(g);
   0: (18) r1 = map[id:283][0]+0
       18 21 00 00 1b 01 00 00 00 00 00 00 00 00 00 00
; int m = test(g);
   2: (61) r6 = *(u32 *)(r1 +0)
       61 16 00 00 00 00 00 00
   3: (bf) r1 = r6
       bf 61 00 00 00 00 00 00
   4: (85) call pc+2#0xffffffffc01992d4                       // correct offset is extracted from field 'off', not imm
       85 10 02 00 01 00 00 00
; return m + g;
   5: (0f) r0 += r6
       0f 60 00 00 00 00 00 00
; return m + g;
   6: (95) exit
       95 00 00 00 00 00 00 00
int test(int i):
; static __noinline int test(int i) {
   7: (bf) r0 = r1
       bf 10 00 00 00 00 00 00
; return i + 1;
   8: (07) r0 += 1
       07 00 00 00 01 00 00 00
; return i + 1;
   9: (95) exit
       95 00 00 00 00 00 00 00

Version information

github.com/cilium/ebpf v0.17.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions