net/bpf/test_run.c | 7 +++++++ 1 file changed, 7 insertions(+)
From: Feng Yang <yangfeng@kylinos.cn>
The bpf_lwt_xmit_push_encap helper needs to access skb_dst(skb)->dev to
calculate the needed headroom:
err = skb_cow_head(skb,
len + LL_RESERVED_SPACE(skb_dst(skb)->dev));
But skb->_skb_refdst may not be initialized when the skb is set up by
bpf_prog_test_run_skb function. Executing bpf_lwt_push_ip_encap function
in this scenario will trigger null pointer dereference, causing a kernel
crash as Yinhao reported:
[ 105.186365] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 105.186382] #PF: supervisor read access in kernel mode
[ 105.186388] #PF: error_code(0x0000) - not-present page
[ 105.186393] PGD 121d3d067 P4D 121d3d067 PUD 106c83067 PMD 0
[ 105.186404] Oops: 0000 [#1] PREEMPT SMP NOPTI
[ 105.186412] CPU: 3 PID: 3250 Comm: poc Kdump: loaded Not tainted 6.19.0-rc5 #1
[ 105.186423] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 105.186427] RIP: 0010:bpf_lwt_push_ip_encap+0x1eb/0x520
[ 105.186443] Code: 0f 84 de 01 00 00 0f b7 4a 04 66 85 c9 0f 85 47 01 00 00 31 c0 5b 5d 41 5c 41 5d 41 5e c3 cc cc cc cc 48 8b 73 58 48 83 e6 fe <48> 8b 36 0f b7 be ec 00 00 00 0f b7 b6 e6 00 00 00 01 fe 83 e6 f0
[ 105.186449] RSP: 0018:ffffbb0e0387bc50 EFLAGS: 00010246
[ 105.186455] RAX: 000000000000004e RBX: ffff94c74e036500 RCX: ffff94c74874da00
[ 105.186460] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff94c74e036500
[ 105.186463] RBP: 0000000000000001 R08: 0000000000000002 R09: 0000000000000000
[ 105.186467] R10: ffffbb0e0387bd50 R11: 0000000000000000 R12: ffffbb0e0387bc98
[ 105.186471] R13: 0000000000000014 R14: 0000000000000000 R15: 0000000000000002
[ 105.186484] FS: 00007f166aa4d680(0000) GS:ffff94c8b7780000(0000) knlGS:0000000000000000
[ 105.186490] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 105.186494] CR2: 0000000000000000 CR3: 000000015eade001 CR4: 0000000000770ee0
[ 105.186499] PKRU: 55555554
[ 105.186502] Call Trace:
[ 105.186507] <TASK>
[ 105.186513] bpf_lwt_xmit_push_encap+0x2b/0x40
[ 105.186522] bpf_prog_a75eaad51e517912+0x41/0x49
[ 105.186536] ? kvm_clock_get_cycles+0x18/0x30
[ 105.186547] ? ktime_get+0x3c/0xa0
[ 105.186554] bpf_test_run+0x195/0x320
[ 105.186563] ? bpf_test_run+0x10f/0x320
[ 105.186579] bpf_prog_test_run_skb+0x2f5/0x4f0
[ 105.186590] __sys_bpf+0x69c/0xa40
[ 105.186603] __x64_sys_bpf+0x1e/0x30
[ 105.186611] do_syscall_64+0x59/0x110
[ 105.186620] entry_SYSCALL_64_after_hwframe+0x76/0xe0
[ 105.186649] RIP: 0033:0x7f166a97455d
Temporarily add the setting of skb->_skb_refdst before bpf_test_run to resolve the issue.
Fixes: 52f278774e79 ("bpf: implement BPF_LWT_ENCAP_IP mode in bpf_lwt_push_encap")
Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
Signed-off-by: Yun Lu <luyun@kylinos.cn>
Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
---
Changes in v3:
- use dst_init
- Link to v2: https://lore.kernel.org/all/20260205092227.126665-1-yangfeng59949@163.com/
Changes in v2:
- Link to v1: https://lore.kernel.org/all/20260127084520.13890-1-luyun_611@163.com/
---
net/bpf/test_run.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 178c4738e63b..3e1c47d53b82 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -989,6 +989,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
struct net *net = current->nsproxy->net_ns;
struct net_device *dev = net->loopback_dev;
+ struct dst_entry bpf_test_run_lwt_xmit_dst;
u32 headroom = NET_SKB_PAD + NET_IP_ALIGN;
u32 linear_sz = kattr->test.data_size_in;
u32 repeat = kattr->test.repeat;
@@ -1156,6 +1157,12 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
skb->ip_summed = CHECKSUM_COMPLETE;
}
+ if (prog->type == BPF_PROG_TYPE_LWT_XMIT) {
+ dst_init(&bpf_test_run_lwt_xmit_dst, NULL, NULL,
+ DST_OBSOLETE_NONE, DST_NOCOUNT);
+ bpf_test_run_lwt_xmit_dst.dev = dev;
+ skb_dst_set_noref(skb, &bpf_test_run_lwt_xmit_dst);
+ }
ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
if (ret)
goto out;
--
2.43.0
syzbot ci has tested the following series [v3] bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap https://lore.kernel.org/all/20260206055113.63476-1-yangfeng59949@163.com * [PATCH v3] bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap and found the following issue: WARNING in skb_dst_set_noref Full report is available here: https://ci.syzbot.org/series/ebdff606-6251-4db9-ab50-448f5433094a *** WARNING in skb_dst_set_noref tree: bpf-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next.git base: 1ace9bac1ad2bc6a0a70baaa16d22b7e783e88c5 arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/673700c1-fa90-4aa2-8342-e6b397961829/config C repro: https://ci.syzbot.org/findings/ad5a5f81-3d84-45ac-90ec-9a169eb16405/c_repro syz repro: https://ci.syzbot.org/findings/ad5a5f81-3d84-45ac-90ec-9a169eb16405/syz_repro ------------[ cut here ]------------ !rcu_read_lock_held() && !rcu_read_lock_bh_held() WARNING: ./include/linux/skbuff.h:1235 at skb_dst_set_noref+0x14a/0x1a0 include/linux/skbuff.h:1235, CPU#1: syz.0.17/5979 Modules linked in: CPU: 1 UID: 0 PID: 5979 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:skb_dst_set_noref+0x14a/0x1a0 include/linux/skbuff.h:1235 Code: 5d 00 48 83 c4 08 5b 41 5c 41 5d 41 5e 41 5f 5d e9 9b 80 e9 01 cc e8 95 58 30 f8 90 0f 0b 90 e9 2f ff ff ff e8 87 58 30 f8 90 <0f> 0b 90 e9 5d ff ff ff 44 89 e1 80 e1 07 38 c1 0f 8c 76 ff ff ff RSP: 0018:ffffc90004487a20 EFLAGS: 00010293 RAX: ffffffff89923f99 RBX: ffffc90004487ba0 RCX: ffff888103713a80 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000000 R08: ffffc90004487be3 R09: 1ffff92000890f7c R10: dffffc0000000000 R11: fffff52000890f7d R12: 0000000000000000 R13: ffff88817331d858 R14: 1ffff1102e663b0b R15: ffff88817331d800 FS: 0000555590ae6500(0000) GS:ffff8882a9928000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2fb63fff CR3: 00000001139cc000 CR4: 00000000000006f0 Call Trace: <TASK> bpf_prog_test_run_skb+0xed8/0x1eb0 net/bpf/test_run.c:1164 bpf_prog_test_run+0x2c7/0x340 kernel/bpf/syscall.c:4721 __sys_bpf+0x643/0x950 kernel/bpf/syscall.c:6246 __do_sys_bpf kernel/bpf/syscall.c:6341 [inline] __se_sys_bpf kernel/bpf/syscall.c:6339 [inline] __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6339 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:0x7f21c579acb9 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:00007fff4c8461d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000141 RAX: ffffffffffffffda RBX: 00007f21c5a15fa0 RCX: 00007f21c579acb9 RDX: 0000000000000050 RSI: 0000200000000780 RDI: 000000000000000a RBP: 00007f21c5808bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f21c5a15fac R14: 00007f21c5a15fa0 R15: 00007f21c5a15fa0 </TASK> *** 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.
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -989,6 +989,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
> u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> struct net *net = current->nsproxy->net_ns;
> struct net_device *dev = net->loopback_dev;
> + struct dst_entry bpf_test_run_lwt_xmit_dst;
> u32 headroom = NET_SKB_PAD + NET_IP_ALIGN;
[ ... ]
> @@ -1156,6 +1157,12 @@
> skb->ip_summed = CHECKSUM_COMPLETE;
> }
>
> + if (prog->type == BPF_PROG_TYPE_LWT_XMIT) {
> + dst_init(&bpf_test_run_lwt_xmit_dst, NULL, NULL,
> + DST_OBSOLETE_NONE, DST_NOCOUNT);
> + bpf_test_run_lwt_xmit_dst.dev = dev;
> + skb_dst_set_noref(skb, &bpf_test_run_lwt_xmit_dst);
> + }
Will skb_dst_set_noref() trigger a WARN_ON here? Looking at the function
in include/linux/skbuff.h:
static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
{
skb_dst_check_unset(skb);
WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
...
}
This code runs from syscall context in bpf_prog_test_run_skb() before
bpf_test_run() is called. At this point, neither rcu_read_lock() nor
local_bh_disable() is held - local_bh_disable() is only called inside
bpf_test_run().
Should the dst setup be wrapped with rcu_read_lock()/rcu_read_unlock(),
or moved inside bpf_test_run() where RCU-bh context is already held?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21740645384
AI-authorship-score: low
AI-authorship-explanation: The commit shows human authorship with real bug reporters from HUST, actual crash stack trace, self-aware comment using Temporarily, and author from kylinos.cn Linux distribution company.
issues-found: 1
issue-severity-score: low
issue-severity-explanation: WARN_ON will trigger in skb_dst_set_noref due to missing RCU context, causing kernel log warnings but no functional impact.
© 2016 - 2026 Red Hat, Inc.