On Mon, Apr 14, 2025 at 2:23 PM Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> wrote: > > syzkaller reported a splat below. [0] > > It always followed another splat by fault injection in > bpf_int_jit_compile(). [1] > > Instead of proceeding with __bpf_prog_ret0_warn() and seeing > a splat later, let's return -ENOMEM to userspace. > > [0]: > WARNING: CPU: 1 PID: 36 at kernel/bpf/core.c:2357 __bpf_prog_ret0_warn+0xa/0x10 kernel/bpf/core.c:2357 > Modules linked in: > CPU: 1 UID: 0 PID: 36 Comm: kworker/1:1 Not tainted 6.14.0-13344-ga9843689e2de #28 PREEMPT(voluntary) 167b7ecb8f281ed56016416cdf1d8bb342db88fc > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 > Workqueue: mld mld_ifc_work > RIP: 0010:__bpf_prog_ret0_warn+0xa/0x10 kernel/bpf/core.c:2357 > Code: ff eb 84 e8 b8 cf ee ff e9 7a ff ff ff e8 ae cf ee ff e9 70 ff ff ff 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa e8 97 cf ee ff 90 <0f> 0b 90 31 c0 c3 f3 0f 1e fa 55 48 89 e5 41 57 41 56 41 55 41 54 > RSP: 0000:ffa0000000267050 EFLAGS: 00010293 > RAX: ffffffff81881569 RBX: ffa0000000393030 RCX: ff11000100dc4500 > RDX: 0000000000000000 RSI: ffa0000000393048 RDI: ff1100010b812a00 > RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000000 > R10: dffffc0000000000 R11: fffffbfff0e5ef77 R12: 0000000000000000 > R13: dffffc0000000000 R14: ff1100010b812a00 R15: ffa0000000393048 > FS: 0000000000000000(0000) GS:ff11000192213000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 00007ff451d686ec CR3: 00000001037eb004 CR4: 0000000000771ef0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000600 > PKRU: 55555554 > Call Trace: > <TASK> > bpf_dispatcher_nop_func include/linux/bpf.h:1316 [inline] > __bpf_prog_run include/linux/filter.h:718 [inline] > bpf_prog_run include/linux/filter.h:725 [inline] > bpf_prog_run_pin_on_cpu include/linux/filter.h:742 [inline] > bpf_prog_run_clear_cb+0x7f/0x140 include/linux/filter.h:983 > run_filter+0x156/0x260 net/packet/af_packet.c:2135 > packet_rcv+0x491/0x15b0 net/packet/af_packet.c:2208 > dev_queue_xmit_nit+0xc27/0xcb0 net/core/dev.c:2592 > xmit_one net/core/dev.c:3831 [inline] > dev_hard_start_xmit+0x1d5/0x720 net/core/dev.c:3851 > sch_direct_xmit+0x242/0x4a0 net/sched/sch_generic.c:343 > __dev_xmit_skb net/core/dev.c:4127 [inline] > __dev_queue_xmit+0x186d/0x37a0 net/core/dev.c:4654 > dev_queue_xmit include/linux/netdevice.h:3355 [inline] > neigh_hh_output include/net/neighbour.h:523 [inline] > neigh_output include/net/neighbour.h:537 [inline] > ip6_finish_output2+0x11f3/0x16e0 net/ipv6/ip6_output.c:141 > dst_output include/net/dst.h:459 [inline] > NF_HOOK+0x160/0x470 include/linux/netfilter.h:314 > mld_sendpack+0x7f7/0xd70 net/ipv6/mcast.c:1868 > mld_send_cr net/ipv6/mcast.c:2169 [inline] > mld_ifc_work+0x835/0xde0 net/ipv6/mcast.c:2702 > process_one_work kernel/workqueue.c:3238 [inline] > process_scheduled_works+0xa77/0x16a0 kernel/workqueue.c:3319 > worker_thread+0x8b6/0xd50 kernel/workqueue.c:3400 > kthread+0x413/0x870 kernel/kthread.c:464 > ret_from_fork+0x48/0x80 arch/x86/kernel/process.c:153 > ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:245 > </TASK> > > [1]: > FAULT_INJECTION: forcing a failure. > name failslab, interval 1, probability 0, space 0, times 1 > CPU: 1 UID: 0 PID: 4562 Comm: syz.4.1225 Not tainted 6.14.0-13344-ga9843689e2de #28 PREEMPT(voluntary) 167b7ecb8f281ed56016416cdf1d8bb342db88fc > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 > Call Trace: > <TASK> > dump_stack_lvl+0xfa/0x120 > should_fail_ex+0x501/0x610 > should_failslab+0xba/0x120 > __kmalloc_cache_noprof+0x5d/0x310 > bpf_int_jit_compile+0x1292/0x18b0 > bpf_prog_select_runtime+0x439/0x780 > > Fixes: fa9dd599b4da ("bpf: get rid of pure_initcall dependency to enable jits") The Fixes tag looks wrong and I suspect you root caused it incorrectly and the "fix" adds a ton of churn for no good reason. If CONFIG_BPF_JIT_ALWAYS_ON=y and JIT fails for whatever reason the following should have executed: fp = bpf_int_jit_compile(fp); bpf_prog_jit_attempt_done(fp); if (!fp->jited && jit_needed) { *err = -ENOTSUPP; return fp; } so the prog won't load and won't execute. jit_needed will be false if CONFIG_BPF_JIT_ALWAYS_ON=n and if fp->jit_requested == true then ret0_warn may indeed stay. Then the fix is probably just this hunk: diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index ba6b6118cf50..662c1bd9937f 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2493,7 +2493,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) fp = bpf_int_jit_compile(fp); bpf_prog_jit_attempt_done(fp); - if (!fp->jited && jit_needed) { + if (!fp->jited && (fp->jit_requested || jit_needed)) { or maybe this instead: - bool jit_needed = false; + bool jit_needed = fp->jit_requested; pw-bot: cr