* [PATCH v9 bpf-next 0/2] Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap
@ 2026-03-03 7:44 Feng Yang
2026-03-03 7:44 ` [PATCH v9 bpf-next 1/2] bpf: test_run: " Feng Yang
2026-03-03 7:44 ` [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap Feng Yang
0 siblings, 2 replies; 5+ messages in thread
From: Feng Yang @ 2026-03-03 7:44 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, posk, ast, daniel, andrii,
martin.lau, eddyz87
Cc: bpf, netdev, linux-kernel, linux-kselftest, yangfeng59949
From: Feng Yang <yangfeng@kylinos.cn>
Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap
Changes in v9:
- Use dst_hold() and skb_dst_set().
!skb_dst skip.
Move all changes into the IS_ENABLED(CONFIG_IPV6).
Use #if IS_ENABLED(CONFIG_IPV6); otherwise, a compilation error will occur when ipv6 is not enabled.
Thanks, Martin KaFai Lau.
- Link to v8: https://lore.kernel.org/all/20260227082133.96951-1-yangfeng59949@163.com/
Changes in v8:
- set ret to an error code before goto out.
- Link to v7: https://lore.kernel.org/all/20260226095156.117996-1-yangfeng59949@163.com/
Changes in v7:
- Use ip6_null_entry to avoid. Thanks, Martin KaFai Lau.
Changes in v6:
- Modify the bpf_lwt_xmit_push_encap function and add selftests for it.
Thanks, Martin KaFai Lau.
- Link to v5: https://lore.kernel.org/all/20260210090657.86977-1-yangfeng59949@163.com/
Changes in v5:
- Refer to the bpf_lwt_xmit_reroute function to configure the dst parameter.
- Link to v4: https://lore.kernel.org/all/20260209015111.28144-1-yangfeng59949@163.com/
Changes in v4:
- add rcu lock
- Link to v3: https://lore.kernel.org/all/20260206055113.63476-1-yangfeng59949@163.com/
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/
Feng Yang (2):
bpf: test_run: Fix the null pointer dereference issue in
bpf_lwt_xmit_push_encap
selftests/bpf: Add selftests for the invocation of
bpf_lwt_xmit_push_encap
net/bpf/test_run.c | 17 ++++++++++++++++
.../selftests/bpf/progs/verifier_lwt.c | 20 +++++++++++++++++++
2 files changed, 37 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v9 bpf-next 1/2] bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap
2026-03-03 7:44 [PATCH v9 bpf-next 0/2] Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap Feng Yang
@ 2026-03-03 7:44 ` Feng Yang
2026-03-03 21:31 ` Martin KaFai Lau
2026-03-03 7:44 ` [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap Feng Yang
1 sibling, 1 reply; 5+ messages in thread
From: Feng Yang @ 2026-03-03 7:44 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, posk, ast, daniel, andrii,
martin.lau, eddyz87
Cc: bpf, netdev, linux-kernel, linux-kselftest, yangfeng59949
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>
Closes: https://groups.google.com/g/hust-os-kernel-patches/c/8-a0kPpBW2s
Signed-off-by: Yun Lu <luyun@kylinos.cn>
Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
Tested-by: syzbot@syzkaller.appspotmail.com
---
net/bpf/test_run.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 178c4738e63b..a086cee1ac6a 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -1156,6 +1156,23 @@ 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) {
+ ret = -EOPNOTSUPP;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (ipv6_bpf_stub) {
+ dst_hold(&net->ipv6.ip6_null_entry->dst);
+ skb_dst_set(skb, &net->ipv6.ip6_null_entry->dst);
+ } else {
+ pr_warn_once("Please test this program with the IPv6 module loaded\n");
+ goto out;
+ }
+#else
+ pr_warn_once("Please test this program with the IPv6 module enabled\n");
+ goto out;
+#endif
+ }
+
ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
if (ret)
goto out;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap
2026-03-03 7:44 [PATCH v9 bpf-next 0/2] Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap Feng Yang
2026-03-03 7:44 ` [PATCH v9 bpf-next 1/2] bpf: test_run: " Feng Yang
@ 2026-03-03 7:44 ` Feng Yang
2026-03-03 21:13 ` Martin KaFai Lau
1 sibling, 1 reply; 5+ messages in thread
From: Feng Yang @ 2026-03-03 7:44 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, posk, ast, daniel, andrii,
martin.lau, eddyz87
Cc: bpf, netdev, linux-kernel, linux-kselftest, yangfeng59949
From: Feng Yang <yangfeng@kylinos.cn>
Calling bpf_lwt_xmit_push_encap will not cause a crash when dst is missing.
Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
---
.../selftests/bpf/progs/verifier_lwt.c | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_lwt.c b/tools/testing/selftests/bpf/progs/verifier_lwt.c
index 5ab746307309..9cef07e6eceb 100644
--- a/tools/testing/selftests/bpf/progs/verifier_lwt.c
+++ b/tools/testing/selftests/bpf/progs/verifier_lwt.c
@@ -231,4 +231,24 @@ __naked void not_permitted_for_lwt_prog(void)
: __clobber_all);
}
+SEC("lwt_xmit")
+__description("missing dst when calling bpf_lwt_xmit_push_encap")
+__success __retval(0)
+__naked void missing_dst_call_bpf_lwt_xmit_push_encap(void)
+{
+ asm volatile (" \
+ r9 = 69; \
+ r3 = r10; \
+ r3 += -32; \
+ *(u64 *)(r3 + 0) = r9; \
+ r2 = 2; \
+ r4 = 20; \
+ call %[bpf_lwt_push_encap]; \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_lwt_push_encap)
+ : __clobber_all);
+}
+
char _license[] SEC("license") = "GPL";
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap
2026-03-03 7:44 ` [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap Feng Yang
@ 2026-03-03 21:13 ` Martin KaFai Lau
0 siblings, 0 replies; 5+ messages in thread
From: Martin KaFai Lau @ 2026-03-03 21:13 UTC (permalink / raw)
To: Feng Yang
Cc: davem, edumazet, kuba, pabeni, horms, posk, ast, daniel, andrii,
eddyz87, bpf, netdev, linux-kernel, linux-kselftest
On 3/2/26 11:44 PM, Feng Yang wrote:
> From: Feng Yang <yangfeng@kylinos.cn>
>
> Calling bpf_lwt_xmit_push_encap will not cause a crash when dst is missing.
>
> Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
> ---
> .../selftests/bpf/progs/verifier_lwt.c | 20 +++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/verifier_lwt.c b/tools/testing/selftests/bpf/progs/verifier_lwt.c
> index 5ab746307309..9cef07e6eceb 100644
> --- a/tools/testing/selftests/bpf/progs/verifier_lwt.c
> +++ b/tools/testing/selftests/bpf/progs/verifier_lwt.c
> @@ -231,4 +231,24 @@ __naked void not_permitted_for_lwt_prog(void)
> : __clobber_all);
> }
>
> +SEC("lwt_xmit")
> +__description("missing dst when calling bpf_lwt_xmit_push_encap")
> +__success __retval(0)
> +__naked void missing_dst_call_bpf_lwt_xmit_push_encap(void)
> +{
> + asm volatile (" \
> + r9 = 69; \
hmm... I just noticed this.
69 is the ip version and ihl?
> + r3 = r10; \
> + r3 += -32; \
> + *(u64 *)(r3 + 0) = r9; \
This will not work in big endian. Although x86 arch is enough to cover
this test, these little things (e.g., the value 69, unnecessary asm
...etc) make this test hard to read.
Let's bite the bullet and move this bpf test prog out of verifier_lwt.c.
It is not testing the verifier to begin with. No need to write in asm
either. Create its own progs/lwt_misc.c test file for misc lwt tests.
Create a corresponding prog_tests/lwt_misc.c also. Write the bpf prog in
C instead of asm. Use "char iph[20];" for the iph and init "iph[0] =
0x45". Search for RUN_TESTS() usage in prog_tests/. It is pretty
straightforward.
pw-bot: cr
> + r2 = 2; \
> + r4 = 20; \
> + call %[bpf_lwt_push_encap]; \
> + r0 = 0; \
> + exit; \
> +" :
> + : __imm(bpf_lwt_push_encap)
> + : __clobber_all);
> +}
> +
> char _license[] SEC("license") = "GPL";
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v9 bpf-next 1/2] bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap
2026-03-03 7:44 ` [PATCH v9 bpf-next 1/2] bpf: test_run: " Feng Yang
@ 2026-03-03 21:31 ` Martin KaFai Lau
0 siblings, 0 replies; 5+ messages in thread
From: Martin KaFai Lau @ 2026-03-03 21:31 UTC (permalink / raw)
To: Feng Yang
Cc: davem, edumazet, kuba, pabeni, horms, posk, ast, daniel, andrii,
eddyz87, bpf, netdev, linux-kernel, linux-kselftest
On 3/2/26 11:44 PM, Feng Yang wrote:
> 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>
> Closes: https://groups.google.com/g/hust-os-kernel-patches/c/8-a0kPpBW2s
> Signed-off-by: Yun Lu <luyun@kylinos.cn>
> Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
> Tested-by: syzbot@syzkaller.appspotmail.com
> ---
> net/bpf/test_run.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index 178c4738e63b..a086cee1ac6a 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -1156,6 +1156,23 @@ 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) {
> + ret = -EOPNOTSUPP;
> +
> +#if IS_ENABLED(CONFIG_IPV6)
It is needed for the "net->ipv6"?
> + if (ipv6_bpf_stub) {
> + dst_hold(&net->ipv6.ip6_null_entry->dst);
> + skb_dst_set(skb, &net->ipv6.ip6_null_entry->dst);
> + } else {
> + pr_warn_once("Please test this program with the IPv6 module loaded\n");
> + goto out;
> + }
> +#else
> + pr_warn_once("Please test this program with the IPv6 module enabled\n");
This is almost the same as the previous pr_warn_once.
Since it needs a respin, lets see if it can be simplified.
> + goto out;
> +#endif
Like this:
if (prog->type == BPF_PROG_TYPE_LWT_XMIT) {
if (ipv6_bpf_stub) {
#if IS_ENABLED(CONFIG_IPV6)
dst_hold(&net->ipv6.ip6_null_entry->dst);
skb_dst_set(skb, &net->ipv6.ip6_null_entry->dst);
#endif
} else {
/* For CONFIG_IPV6=n, ipv6_bpf_stub is NULL */
pr_err_once("Please test this program with the IPv6 module loaded\n");
ret = -EOPNOTSUPP;
goto out;
}
}
> + }
> +
> ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
> if (ret)
> goto out;
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-03 21:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-03 7:44 [PATCH v9 bpf-next 0/2] Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap Feng Yang
2026-03-03 7:44 ` [PATCH v9 bpf-next 1/2] bpf: test_run: " Feng Yang
2026-03-03 21:31 ` Martin KaFai Lau
2026-03-03 7:44 ` [PATCH v9 bpf-next 2/2] selftests/bpf: Add selftests for the invocation of bpf_lwt_xmit_push_encap Feng Yang
2026-03-03 21:13 ` Martin KaFai Lau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox