[PATCH bpf 0/2] bpf: Fix memory access flags in helper prototypes

Zesen Liu posted 2 patches 1 month ago
There is a newer version of this series
kernel/bpf/helpers.c     |  2 +-
kernel/bpf/syscall.c     |  2 +-
kernel/bpf/verifier.c    | 17 +++++++++++++++++
kernel/trace/bpf_trace.c |  6 +++---
net/core/filter.c        |  8 ++++----
5 files changed, 26 insertions(+), 9 deletions(-)
[PATCH bpf 0/2] bpf: Fix memory access flags in helper prototypes
Posted by Zesen Liu 1 month ago
Hi,

This series adds missing memory access flags (MEM_RDONLY or MEM_WRITE) to
several bpf helper function prototypes that use ARG_PTR_TO_MEM but lack the
correct flag. It also adds a new check in verifier to ensure the flag is
specified.

Missing memory access flags in helper prototypes can lead to critical
correctness issues when the verifier tries to perform code optimization.
After commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type
tracking"), the verifier relies on the memory access flags, rather than
treating all arguments in helper functions as potentially modifying the
pointed-to memory.

Using ARG_PTR_TO_MEM alone without flags does not make sense because:

- If the helper does not change the argument, missing MEM_RDONLY causes the
   verifier to incorrectly reject a read-only buffer.
- If the helper does change the argument, missing MEM_WRITE causes the
   verifier to incorrectly assume the memory is unchanged, leading to
   errors in code optimization.

We have already seen several reports regarding this:

- commit ac44dcc788b9 ("bpf: Fix verifier assumptions of bpf_d_path's
   output buffer") adds MEM_WRITE to bpf_d_path;
- commit 2eb7648558a7 ("bpf: Specify access type of bpf_sysctl_get_name
   args") adds MEM_WRITE to bpf_sysctl_get_name.

This series looks through all prototypes in the kernel and completes the
flags. It also adds a new check (check_func_proto) in
verifier.c to statically restrict ARG_PTR_TO_MEM from appearing without
memory access flags. 

Thanks,

Zesen Liu

---
Zesen Liu (2):
      bpf: Fix memory access flags in helper prototypes
      bpf: Require ARG_PTR_TO_MEM with memory flag

 kernel/bpf/helpers.c     |  2 +-
 kernel/bpf/syscall.c     |  2 +-
 kernel/bpf/verifier.c    | 17 +++++++++++++++++
 kernel/trace/bpf_trace.c |  6 +++---
 net/core/filter.c        |  8 ++++----
 5 files changed, 26 insertions(+), 9 deletions(-)
---
base-commit: ab86d0bf01f6d0e37fd67761bb62918321b64efc
change-id: 20251220-helper_proto-fb6e64182467

Best regards,
-- 
Zesen Liu <ftyghome@gmail.com>
[syzbot ci] Re: bpf: Fix memory access flags in helper prototypes
Posted by syzbot ci 1 month ago
syzbot ci has tested the following series

[v1] bpf: Fix memory access flags in helper prototypes
https://lore.kernel.org/all/20260107-helper_proto-v1-0-e387e08271cc@gmail.com
* [PATCH bpf 1/2] bpf: Fix memory access flags in helper prototypes
* [PATCH bpf 2/2] bpf: Require ARG_PTR_TO_MEM with memory flag

and found the following issue:
WARNING in check_helper_call

Full report is available here:
https://ci.syzbot.org/series/020c2fa8-b95d-4273-9bc0-2f82fa714a8e

***

WARNING in check_helper_call

tree:      bpf
URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf.git
base:      ab86d0bf01f6d0e37fd67761bb62918321b64efc
arch:      amd64
compiler:  Debian clang version 21.1.8 (++20251202083448+f68f64eb8130-1~exp1~20251202083504.46), Debian LLD 21.1.8
config:    https://ci.syzbot.org/builds/9a24b0e7-35e4-4718-b939-3b210b6b5126/config
C repro:   https://ci.syzbot.org/findings/8fcbdcf8-4480-46d8-b7a8-f1de9401a8ac/c_repro
syz repro: https://ci.syzbot.org/findings/8fcbdcf8-4480-46d8-b7a8-f1de9401a8ac/syz_repro

------------[ cut here ]------------
verifier bug: incorrect func proto bpf_tcp_raw_check_syncookie_ipv6#207
WARNING: kernel/bpf/verifier.c:11546 at check_helper_call+0xc00/0x6e10 kernel/bpf/verifier.c:11546, CPU#0: syz.0.17/5981
Modules linked in:
CPU: 0 UID: 0 PID: 5981 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:check_helper_call+0xc16/0x6e10 kernel/bpf/verifier.c:11546
Code: ef e6 ff 49 bf 00 00 00 00 00 fc ff df 48 8d 1d a0 c2 ea 0d 44 8b 64 24 24 44 89 e7 e8 d3 32 0c 00 48 89 df 48 89 c6 44 89 e2 <67> 48 0f b9 3a 49 81 c6 80 08 00 00 44 89 e7 e8 b6 32 0c 00 4c 89
RSP: 0018:ffffc90007116fa0 EFLAGS: 00010246
RAX: ffffffff8b934740 RBX: ffffffff8fc645d0 RCX: dffffc0000000000
RDX: 00000000000000cf RSI: ffffffff8b934740 RDI: ffffffff8fc645d0
RBP: ffffc900071171b0 R08: ffff88816b42ba80 R09: 0000000000000002
R10: 0000000000000004 R11: 0000000000000000 R12: 00000000000000cf
R13: f8f8f8f8f8f8f8f8 R14: ffff888112440000 R15: dffffc0000000000
FS:  000055557af7b500(0000) GS:ffff88818e40e000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd892207dac CR3: 0000000161682000 CR4: 00000000000006f0
Call Trace:
 <TASK>
 do_check_insn kernel/bpf/verifier.c:20417 [inline]
 do_check+0x99eb/0xec30 kernel/bpf/verifier.c:20598
 do_check_common+0x19cc/0x25b0 kernel/bpf/verifier.c:23882
 do_check_main kernel/bpf/verifier.c:23965 [inline]
 bpf_check+0x5f0d/0x1c4a0 kernel/bpf/verifier.c:25272
 bpf_prog_load+0x1484/0x1ae0 kernel/bpf/syscall.c:3088
 __sys_bpf+0x570/0x920 kernel/bpf/syscall.c:6164
 __do_sys_bpf kernel/bpf/syscall.c:6274 [inline]
 __se_sys_bpf kernel/bpf/syscall.c:6272 [inline]
 __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6272
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd891f9acb9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffee24b6bb8 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
RAX: ffffffffffffffda RBX: 00007fd892205fa0 RCX: 00007fd891f9acb9
RDX: 0000000000000094 RSI: 0000200000000300 RDI: 0000000000000005
RBP: 00007fd892008bf7 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fd892205fac R14: 00007fd892205fa0 R15: 00007fd892205fa0
 </TASK>
----------------
Code disassembly (best guess):
   0:	ef                   	out    %eax,(%dx)
   1:	e6 ff                	out    %al,$0xff
   3:	49 bf 00 00 00 00 00 	movabs $0xdffffc0000000000,%r15
   a:	fc ff df
   d:	48 8d 1d a0 c2 ea 0d 	lea    0xdeac2a0(%rip),%rbx        # 0xdeac2b4
  14:	44 8b 64 24 24       	mov    0x24(%rsp),%r12d
  19:	44 89 e7             	mov    %r12d,%edi
  1c:	e8 d3 32 0c 00       	call   0xc32f4
  21:	48 89 df             	mov    %rbx,%rdi
  24:	48 89 c6             	mov    %rax,%rsi
  27:	44 89 e2             	mov    %r12d,%edx
* 2a:	67 48 0f b9 3a       	ud1    (%edx),%rdi <-- trapping instruction
  2f:	49 81 c6 80 08 00 00 	add    $0x880,%r14
  36:	44 89 e7             	mov    %r12d,%edi
  39:	e8 b6 32 0c 00       	call   0xc32f4
  3e:	4c                   	rex.WR
  3f:	89                   	.byte 0x89


***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.