Inconsistent BTF entries for `struct pt_regs *regs` parameter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Depending on distribution/kernel/syscall combination, BTF entry for
`struct pt_regs *regs` parameter differs.

For example, Amazon Linux 2 with kernel-5.15 package enabled has a FWD
entry for `__x64_sys_recvmsg` function:

```
$ uname -a
Linux ip-10-1-1-66.ap-northeast-1.compute.internal
5.15.43-20.123.amzn2.x86_64 #1 SMP Fri May 27 00:28:44 UTC 2022 x86_64
x86_64 x86_64 GNU/Linux

$ bpftool btf dump file /sys/kernel/btf/vmlinux format raw
...
[15439] FWD 'pt_regs' fwd_kind=struct
[15440] CONST '(anon)' type_id=15439
[15441] PTR '(anon)' type_id=15440
[15442] FUNC_PROTO '(anon)' ret_type_id=34 vlen=1
        '__unused' type_id=15441
...
[15694] FUNC '__x64_sys_recvmsg' type_id=15442 linkage=static
...
```

while Ubuntu 20.04 LTS with newer kernel has a STRUCT entry for the
same function:

```
$ uname -a
Linux xxx-XPS-13-9300 5.13.0-51-generic #58~20.04.1-Ubuntu SMP Tue Jun
14 11:29:12 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ bpftool btf dump file /sys/kernel/btf/vmlinux format raw
[1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
...
[226] STRUCT 'pt_regs' size=168 vlen=21
        'r15' type_id=1 bits_offset=0
        'r14' type_id=1 bits_offset=64
        'r13' type_id=1 bits_offset=128
        'r12' type_id=1 bits_offset=192
        'bp' type_id=1 bits_offset=256
        'bx' type_id=1 bits_offset=320
        'r11' type_id=1 bits_offset=384
        'r10' type_id=1 bits_offset=448
        'r9' type_id=1 bits_offset=512
        'r8' type_id=1 bits_offset=576
        'ax' type_id=1 bits_offset=640
        'cx' type_id=1 bits_offset=704
        'dx' type_id=1 bits_offset=768
        'si' type_id=1 bits_offset=832
        'di' type_id=1 bits_offset=896
        'orig_ax' type_id=1 bits_offset=960
        'ip' type_id=1 bits_offset=1024
        'cs' type_id=1 bits_offset=1088
        'flags' type_id=1 bits_offset=1152
        'sp' type_id=1 bits_offset=1216
        'ss' type_id=1 bits_offset=1280
...
[5183] CONST '(anon)' type_id=226
...
[5189] PTR '(anon)' type_id=5183
...
[5321] FUNC_PROTO '(anon)' ret_type_id=42 vlen=1
        '__unused' type_id=5189
...
[17648] FUNC '__x64_sys_recvmsg' type_id=5321 linkage=static
...
```

Yet another distribution/kernel/syscall combination has multiple `FUNC
'__x64_sys_[SYSCALL]'` entries, one for FWD and the other for STRUCT:

```
$ uname -a
Linux ip-10-5-0-115.ap-northeast-1.compute.internal
5.10.112-108.499.amzn2.x86_64 #1 SMP Wed Apr 27 23:39:40 UTC 2022
x86_64 x86_64 x86_64 GNU/Linux

```
$ bpftool btf dump file /sys/kernel/btf/vmlinux format raw | grep
__x64_sys_mprotect
...
[175] STRUCT 'pt_regs' size=168 vlen=21
        'r15' type_id=2 bits_offset=0
        'r14' type_id=2 bits_offset=64
        'r13' type_id=2 bits_offset=128
        'r12' type_id=2 bits_offset=192
        'bp' type_id=2 bits_offset=256
...
[4215] CONST '(anon)' type_id=175
...
[4220] PTR '(anon)' type_id=4215
...
[6062] FUNC_PROTO '(anon)' ret_type_id=36 vlen=1
        'regs' type_id=4220
...
[11461] FWD 'pt_regs' fwd_kind=struct
[11462] CONST '(anon)' type_id=11461
[11463] PTR '(anon)' type_id=11462
[11464] FUNC_PROTO '(anon)' ret_type_id=36 vlen=1
        '__unused' type_id=11463
...
[11698] FUNC '__x64_sys_mprotect' type_id=11464 linkage=static
...
[23528] FUNC '__x64_sys_mprotect' type_id=6062 linkage=static
...
```

Trying to read `regs` parameter with FWD entry results in "invalid
bpf_context access" error:

```
SEC("fentry/__x64_sys_recvfrom")
int BPF_PROG(fentry_syscall, struct pt_regs *regs) {
  struct event t;

  bpf_get_current_comm(t.comm, TASK_COMM_LEN);

  u64 id = bpf_get_current_pid_tgid();
  t.pid = id >> 32;

  // This causes an error on some environments.
  t.fd = PT_REGS_PARM1_CORE(regs);

  bpf_printk("comm: %s, pid: %d, fd: %d", t.comm, t.pid, t.fd);

  return 0;
```

```
$ sudo ./output
2022/07/01 03:33:01 loading objects: field FentrySyscall: program
fentry_syscall: load program: permission denied:
        arg#0 type is not a struct
        Unrecognized arg#0 type PTR
        ; int BPF_PROG(fentry_syscall, struct pt_regs *regs) {
        0: (79) r6 = *(u64 *)(r1 +0)
        func '__x64_sys_recvfrom' arg0 type FWD is not a struct
        invalid bpf_context access off=0 size=8
        processed 1 insns (limit 1000000) max_states_per_insn 0
total_states 0 peak_states 0 mark_read 0
```

Is this a bug related to toolchain?

I've asked this question to AWS support (owner of Amazon Linux 2) but
they couldn't answer. I've also asked on StackOverflow but no
responses as of now. A cilium/ebpf developer told me to ask here.

* https://stackoverflow.com/questions/72824924/invalid-bpf-context-access-when-trying-to-read-regs-parameter
* https://github.com/cilium/ebpf/issues/723#issuecomment-1190050109
* https://github.com/harai/invalidbpfcontext



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux