* [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
@ 2025-07-22 14:32 Paul Chaignon
2025-07-22 14:33 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load Paul Chaignon
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Paul Chaignon @ 2025-07-22 14:32 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, John Fastabend
The following BPF program, simplified from a syzkaller repro, causes a
kernel warning:
r0 = *(u8 *)(r1 + 169);
exit;
With pointer field sk being at offset 168 in __sk_buff. This access is
detected as a narrower read in bpf_skb_is_valid_access because it
doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
and later proceeds to bpf_convert_ctx_access. At that point,
target_size is null and the verifier errors with a kernel warning and:
verifier bug: error during ctx access conversion(1)
This patch fixes that to return a proper "invalid bpf_context access
off=X size=Y" error on the load instruction.
The same issue affects multiple other fields in context structures that
allow narrow access. Some other non-affected fields (for sk_msg,
sk_lookup, and sockopt) were also changed to use bpf_ctx_range_ptr for
consistency.
Note this syzkaller crash was reported in [1], which used to be about a
different bug, fixed in commit fce7bd8e385a ("bpf/verifier: Handle
BPF_LOAD_ACQ instructions in insn_def_regno()"). Because syzbot somehow
confused the two bugs, the new crash and repro didn't get reported to
the mailing list.
Link: https://syzkaller.appspot.com/bug?extid=0ef84a7bdf5301d4cbec [1]
Fixes: f96da09473b52 ("bpf: simplify narrower ctx access")
Fixes: 0df1a55afa832 ("bpf: Warn on internal verifier errors")
Reported-by: syzbot+0ef84a7bdf5301d4cbec@syzkaller.appspotmail.com
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
---
Changes in v2:
- Use bpf_ctx_range{,_ptr} for a few other fields, for consistency,
as suggested by Eduard and John.
- Fix accesses to skb_hwtstamp, reported by Eduard.
kernel/bpf/cgroup.c | 8 ++++----
net/core/filter.c | 20 ++++++++++----------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 2e1c0eab20c0..180b630279b9 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -2577,22 +2577,22 @@ static bool cg_sockopt_is_valid_access(int off, int size,
}
switch (off) {
- case offsetof(struct bpf_sockopt, sk):
+ case bpf_ctx_range_ptr(struct bpf_sockopt, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET;
break;
- case offsetof(struct bpf_sockopt, optval):
+ case bpf_ctx_range_ptr(struct bpf_sockopt, optval):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET;
break;
- case offsetof(struct bpf_sockopt, optval_end):
+ case bpf_ctx_range_ptr(struct bpf_sockopt, optval_end):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET_END;
break;
- case offsetof(struct bpf_sockopt, retval):
+ case bpf_ctx_range(struct bpf_sockopt, retval):
if (size != size_default)
return false;
return prog->expected_attach_type == BPF_CGROUP_GETSOCKOPT;
diff --git a/net/core/filter.c b/net/core/filter.c
index 7a72f766aacf..47073a0180a4 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -8690,7 +8690,7 @@ static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type
if (size != sizeof(__u64))
return false;
break;
- case offsetof(struct __sk_buff, sk):
+ case bpf_ctx_range_ptr(struct __sk_buff, sk):
if (type == BPF_WRITE || size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCK_COMMON_OR_NULL;
@@ -9268,7 +9268,7 @@ static bool sock_addr_is_valid_access(int off, int size,
return false;
}
break;
- case offsetof(struct bpf_sock_addr, sk):
+ case bpf_ctx_range_ptr(struct bpf_sock_addr, sk):
if (type != BPF_READ)
return false;
if (size != sizeof(__u64))
@@ -9318,17 +9318,17 @@ static bool sock_ops_is_valid_access(int off, int size,
if (size != sizeof(__u64))
return false;
break;
- case offsetof(struct bpf_sock_ops, sk):
+ case bpf_ctx_range_ptr(struct bpf_sock_ops, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET_OR_NULL;
break;
- case offsetof(struct bpf_sock_ops, skb_data):
+ case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET;
break;
- case offsetof(struct bpf_sock_ops, skb_data_end):
+ case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data_end):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_PACKET_END;
@@ -9337,7 +9337,7 @@ static bool sock_ops_is_valid_access(int off, int size,
bpf_ctx_record_field_size(info, size_default);
return bpf_ctx_narrow_access_ok(off, size,
size_default);
- case offsetof(struct bpf_sock_ops, skb_hwtstamp):
+ case bpf_ctx_range(struct bpf_sock_ops, skb_hwtstamp):
if (size != sizeof(__u64))
return false;
break;
@@ -9407,17 +9407,17 @@ static bool sk_msg_is_valid_access(int off, int size,
return false;
switch (off) {
- case offsetof(struct sk_msg_md, data):
+ case bpf_ctx_range_ptr(struct sk_msg_md, data):
info->reg_type = PTR_TO_PACKET;
if (size != sizeof(__u64))
return false;
break;
- case offsetof(struct sk_msg_md, data_end):
+ case bpf_ctx_range_ptr(struct sk_msg_md, data_end):
info->reg_type = PTR_TO_PACKET_END;
if (size != sizeof(__u64))
return false;
break;
- case offsetof(struct sk_msg_md, sk):
+ case bpf_ctx_range_ptr(struct sk_msg_md, sk):
if (size != sizeof(__u64))
return false;
info->reg_type = PTR_TO_SOCKET;
@@ -11623,7 +11623,7 @@ static bool sk_lookup_is_valid_access(int off, int size,
return false;
switch (off) {
- case offsetof(struct bpf_sk_lookup, sk):
+ case bpf_ctx_range_ptr(struct bpf_sk_lookup, sk):
info->reg_type = PTR_TO_SOCKET_OR_NULL;
return size == sizeof(__u64);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load
2025-07-22 14:32 [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Paul Chaignon
@ 2025-07-22 14:33 ` Paul Chaignon
2025-07-22 21:38 ` Eduard Zingerman
2025-07-22 20:40 ` [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Eduard Zingerman
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Paul Chaignon @ 2025-07-22 14:33 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, John Fastabend
This patch adds selftests to cover invalid narrower loads on the
context. These used to cause kernel warnings before the previous patch.
To trigger the warning, the load had to be aligned, to read an affected
context field (ex., skb->sk), and not starting at the beginning of the
field.
The nine new cases all fail without the previous patch.
Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
---
Changes in v2:
- Cover all affected fields, via a macro, as suggested by Eduard.
.../selftests/bpf/progs/verifier_ctx.c | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_ctx.c b/tools/testing/selftests/bpf/progs/verifier_ctx.c
index a83809a1dbbf..0450840c92d9 100644
--- a/tools/testing/selftests/bpf/progs/verifier_ctx.c
+++ b/tools/testing/selftests/bpf/progs/verifier_ctx.c
@@ -218,4 +218,29 @@ __naked void null_check_8_null_bind(void)
: __clobber_all);
}
+#define narrow_load(type, ctx, field) \
+ SEC(type) \
+ __description("narrow load on field " #field " of " #ctx) \
+ __failure __msg("invalid bpf_context access") \
+ __naked void invalid_narrow_load##ctx##field(void) \
+ { \
+ asm volatile (" \
+ r1 = *(u32 *)(r1 + %[off]); \
+ r0 = 0; \
+ exit;" \
+ : \
+ : __imm_const(off, offsetof(struct ctx, field) + 4) \
+ : __clobber_all); \
+ }
+
+narrow_load("cgroup/getsockopt", bpf_sockopt, sk);
+narrow_load("cgroup/getsockopt", bpf_sockopt, optval);
+narrow_load("cgroup/getsockopt", bpf_sockopt, optval_end);
+narrow_load("tc", __sk_buff, sk);
+narrow_load("cgroup/bind4", bpf_sock_addr, sk);
+narrow_load("sockops", bpf_sock_ops, sk);
+narrow_load("sockops", bpf_sock_ops, skb_data);
+narrow_load("sockops", bpf_sock_ops, skb_data_end);
+narrow_load("sockops", bpf_sock_ops, skb_hwtstamp);
+
char _license[] SEC("license") = "GPL";
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
2025-07-22 14:32 [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Paul Chaignon
2025-07-22 14:33 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load Paul Chaignon
@ 2025-07-22 20:40 ` Eduard Zingerman
2025-07-22 22:28 ` Martin KaFai Lau
2025-07-24 2:50 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: Eduard Zingerman @ 2025-07-22 20:40 UTC (permalink / raw)
To: Paul Chaignon, bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
John Fastabend
On Tue, 2025-07-22 at 16:32 +0200, Paul Chaignon wrote:
> The following BPF program, simplified from a syzkaller repro, causes a
> kernel warning:
>
> r0 = *(u8 *)(r1 + 169);
> exit;
>
> With pointer field sk being at offset 168 in __sk_buff. This access is
> detected as a narrower read in bpf_skb_is_valid_access because it
> doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
> and later proceeds to bpf_convert_ctx_access. At that point,
> target_size is null and the verifier errors with a kernel warning and:
>
> verifier bug: error during ctx access conversion(1)
>
> This patch fixes that to return a proper "invalid bpf_context access
> off=X size=Y" error on the load instruction.
>
> The same issue affects multiple other fields in context structures that
> allow narrow access. Some other non-affected fields (for sk_msg,
> sk_lookup, and sockopt) were also changed to use bpf_ctx_range_ptr for
> consistency.
>
> Note this syzkaller crash was reported in [1], which used to be about a
> different bug, fixed in commit fce7bd8e385a ("bpf/verifier: Handle
> BPF_LOAD_ACQ instructions in insn_def_regno()"). Because syzbot somehow
> confused the two bugs, the new crash and repro didn't get reported to
> the mailing list.
>
> Link: https://syzkaller.appspot.com/bug?extid=0ef84a7bdf5301d4cbec [1]
> Fixes: f96da09473b52 ("bpf: simplify narrower ctx access")
> Fixes: 0df1a55afa832 ("bpf: Warn on internal verifier errors")
> Reported-by: syzbot+0ef84a7bdf5301d4cbec@syzkaller.appspotmail.com
> Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
> ---
> Changes in v2:
> - Use bpf_ctx_range{,_ptr} for a few other fields, for consistency,
> as suggested by Eduard and John.
> - Fix accesses to skb_hwtstamp, reported by Eduard.
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load
2025-07-22 14:33 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load Paul Chaignon
@ 2025-07-22 21:38 ` Eduard Zingerman
0 siblings, 0 replies; 8+ messages in thread
From: Eduard Zingerman @ 2025-07-22 21:38 UTC (permalink / raw)
To: Paul Chaignon, bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
John Fastabend
On Tue, 2025-07-22 at 16:33 +0200, Paul Chaignon wrote:
> This patch adds selftests to cover invalid narrower loads on the
> context. These used to cause kernel warnings before the previous patch.
> To trigger the warning, the load had to be aligned, to read an affected
> context field (ex., skb->sk), and not starting at the beginning of the
> field.
>
> The nine new cases all fail without the previous patch.
>
> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
> ---
> Changes in v2:
> - Cover all affected fields, via a macro, as suggested by Eduard.
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
[...]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
2025-07-22 14:32 [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Paul Chaignon
2025-07-22 14:33 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load Paul Chaignon
2025-07-22 20:40 ` [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Eduard Zingerman
@ 2025-07-22 22:28 ` Martin KaFai Lau
2025-07-23 8:13 ` Paul Chaignon
2025-07-24 2:50 ` patchwork-bot+netdevbpf
3 siblings, 1 reply; 8+ messages in thread
From: Martin KaFai Lau @ 2025-07-22 22:28 UTC (permalink / raw)
To: Paul Chaignon
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, John Fastabend
On 7/22/25 7:32 AM, Paul Chaignon wrote:
> The following BPF program, simplified from a syzkaller repro, causes a
> kernel warning:
>
> r0 = *(u8 *)(r1 + 169);
> exit;
>
> With pointer field sk being at offset 168 in __sk_buff. This access is
> detected as a narrower read in bpf_skb_is_valid_access because it
> doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
> and later proceeds to bpf_convert_ctx_access. At that point,
> target_size is null and the verifier errors with a kernel warning and:
I think it meant target_size is 0. I suspect !cnt is the condition causing the
'verifier bug: ...'. Please check. No need to resend. The patch lgtm.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
2025-07-22 22:28 ` Martin KaFai Lau
@ 2025-07-23 8:13 ` Paul Chaignon
2025-07-24 2:42 ` Martin KaFai Lau
0 siblings, 1 reply; 8+ messages in thread
From: Paul Chaignon @ 2025-07-23 8:13 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, John Fastabend
On Tue, Jul 22, 2025 at 03:28:40PM -0700, Martin KaFai Lau wrote:
> On 7/22/25 7:32 AM, Paul Chaignon wrote:
> > The following BPF program, simplified from a syzkaller repro, causes a
> > kernel warning:
> >
> > r0 = *(u8 *)(r1 + 169);
> > exit;
> >
> > With pointer field sk being at offset 168 in __sk_buff. This access is
> > detected as a narrower read in bpf_skb_is_valid_access because it
> > doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
> > and later proceeds to bpf_convert_ctx_access. At that point,
> > target_size is null and the verifier errors with a kernel warning and:
>
> I think it meant target_size is 0. I suspect !cnt is the condition causing
> the 'verifier bug: ...'. Please check. No need to resend. The patch lgtm.
I also initially though the error was triggered because cnt was 0, but
it is not. In case of narrower load, the offset is aligned before
calling convert_ctx_access, which means we match
offsetof(struct __sk_buff, sk) in bpf_convert_ctx_access. An
instruction is added and cnt is thus 1. target_size however stays 0 so
we hit the verifier bug error.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
2025-07-23 8:13 ` Paul Chaignon
@ 2025-07-24 2:42 ` Martin KaFai Lau
0 siblings, 0 replies; 8+ messages in thread
From: Martin KaFai Lau @ 2025-07-24 2:42 UTC (permalink / raw)
To: Paul Chaignon
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, John Fastabend
On 7/23/25 1:13 AM, Paul Chaignon wrote:
> On Tue, Jul 22, 2025 at 03:28:40PM -0700, Martin KaFai Lau wrote:
>> On 7/22/25 7:32 AM, Paul Chaignon wrote:
>>> The following BPF program, simplified from a syzkaller repro, causes a
>>> kernel warning:
>>>
>>> r0 = *(u8 *)(r1 + 169);
>>> exit;
>>>
>>> With pointer field sk being at offset 168 in __sk_buff. This access is
>>> detected as a narrower read in bpf_skb_is_valid_access because it
>>> doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
>>> and later proceeds to bpf_convert_ctx_access. At that point,
>>> target_size is null and the verifier errors with a kernel warning and:
>>
>> I think it meant target_size is 0. I suspect !cnt is the condition causing
>> the 'verifier bug: ...'. Please check. No need to resend. The patch lgtm.
>
> I also initially though the error was triggered because cnt was 0, but
> it is not. In case of narrower load, the offset is aligned before
> calling convert_ctx_access, which means we match
> offsetof(struct __sk_buff, sk) in bpf_convert_ctx_access. An
> instruction is added and cnt is thus 1. target_size however stays 0 so
> we hit the verifier bug error.
Got it. I have added this details to the commit message. Applied. Thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields
2025-07-22 14:32 [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Paul Chaignon
` (2 preceding siblings ...)
2025-07-22 22:28 ` Martin KaFai Lau
@ 2025-07-24 2:50 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-07-24 2:50 UTC (permalink / raw)
To: Paul Chaignon; +Cc: bpf, ast, daniel, andrii, eddyz87, john.fastabend
Hello:
This series was applied to bpf/bpf-next.git (net)
by Martin KaFai Lau <martin.lau@kernel.org>:
On Tue, 22 Jul 2025 16:32:32 +0200 you wrote:
> The following BPF program, simplified from a syzkaller repro, causes a
> kernel warning:
>
> r0 = *(u8 *)(r1 + 169);
> exit;
>
> With pointer field sk being at offset 168 in __sk_buff. This access is
> detected as a narrower read in bpf_skb_is_valid_access because it
> doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed
> and later proceeds to bpf_convert_ctx_access. At that point,
> target_size is null and the verifier errors with a kernel warning and:
>
> [...]
Here is the summary with links:
- [bpf-next,v2,1/2] bpf: Reject narrower access to pointer ctx fields
https://git.kernel.org/bpf/bpf-next/c/e09299225d5b
- [bpf-next,v2,2/2] selftests/bpf: Test invalid narrower ctx load
https://git.kernel.org/bpf/bpf-next/c/ba578b87fe2b
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-07-24 2:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-22 14:32 [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Paul Chaignon
2025-07-22 14:33 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test invalid narrower ctx load Paul Chaignon
2025-07-22 21:38 ` Eduard Zingerman
2025-07-22 20:40 ` [PATCH bpf-next v2 1/2] bpf: Reject narrower access to pointer ctx fields Eduard Zingerman
2025-07-22 22:28 ` Martin KaFai Lau
2025-07-23 8:13 ` Paul Chaignon
2025-07-24 2:42 ` Martin KaFai Lau
2025-07-24 2:50 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).