* [PATCH bpf-next v2 1/2] bpf: Reject writes through untrusted BTF pointers
2026-07-08 3:07 [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
@ 2026-07-08 3:07 ` Kumar Kartikeya Dwivedi
2026-07-08 3:07 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
2026-07-08 7:40 ` [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-08 3:07 UTC (permalink / raw)
To: bpf
Cc: Amery Hung, Nicholas Dudar, Alexei Starovoitov, Andrii Nakryiko,
Daniel Borkmann, Eduard Zingerman, Emil Tsalapatis, kkd,
kernel-team
From: Nicholas Dudar <main.kalliope@gmail.com>
check_ptr_to_btf_access() lets program-type btf_struct_access callbacks
validate writes before the default BTF access path rejects non-read
accesses. That bypasses the read-only policy for untrusted BTF pointers
created by helpers such as bpf_rdonly_cast().
Reject non-read accesses through PTR_UNTRUSTED BTF pointers at the
common entry point, before the callback branch to handle all cases.
Fixes: 282de143ead9 ("bpf: Introduce allocated objects support")
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
kernel/bpf/verifier.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 51f7965d42e3..4f42b4e929ad 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5790,6 +5790,11 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
return -EACCES;
}
+ if (atype != BPF_READ && (type_flag(reg->type) & PTR_UNTRUSTED)) {
+ verbose(env, "only read is supported\n");
+ return -EACCES;
+ }
+
if (env->ops->btf_struct_access && !type_is_alloc(reg->type) && atype == BPF_WRITE) {
if (!btf_is_kernel(reg->btf)) {
verifier_bug(env, "reg->btf must be kernel btf");
@@ -5802,8 +5807,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
reg_arg_name(env, argno), tname, off, size);
} else {
/* Writes are permitted with default btf_struct_access for
- * program allocated objects (which always have id > 0),
- * but not for untrusted PTR_TO_BTF_ID | MEM_ALLOC.
+ * program allocated objects (which always have id > 0).
*/
if (atype != BPF_READ && !type_is_ptr_alloc_obj(reg->type)) {
verbose(env, "only read is supported\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH bpf-next v2 2/2] selftests/bpf: Add untrusted BTF write regression
2026-07-08 3:07 [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
2026-07-08 3:07 ` [PATCH bpf-next v2 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
@ 2026-07-08 3:07 ` Kumar Kartikeya Dwivedi
2026-07-08 7:40 ` [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-08 3:07 UTC (permalink / raw)
To: bpf
Cc: Amery Hung, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Add a TCP congestion-control struct_ops load test for a write through a
BTF pointer produced by bpf_rdonly_cast().
The test expects the verifier to reject the program before the TCP CA
btf_struct_access callback can whitelist the tcp_sock field write.
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
.../selftests/bpf/prog_tests/bpf_tcp_ca.c | 12 +++++++++
.../bpf/progs/tcp_ca_untrusted_btf_write.c | 26 +++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
index fe30181e6336..eb05fc82f81b 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
@@ -14,6 +14,7 @@
#include "tcp_ca_incompl_cong_ops.skel.h"
#include "tcp_ca_unsupp_cong_op.skel.h"
#include "tcp_ca_kfunc.skel.h"
+#include "tcp_ca_untrusted_btf_write.skel.h"
#include "bpf_cc_cubic.skel.h"
static const unsigned int total_bytes = 10 * 1024 * 1024;
@@ -579,6 +580,15 @@ static void test_tcp_ca_kfunc(void)
tcp_ca_kfunc__destroy(skel);
}
+static void test_untrusted_btf_write(void)
+{
+ struct tcp_ca_untrusted_btf_write *skel;
+
+ skel = tcp_ca_untrusted_btf_write__open_and_load();
+ ASSERT_ERR_PTR(skel, "tcp_ca_untrusted_btf_write__open_and_load");
+ tcp_ca_untrusted_btf_write__destroy(skel);
+}
+
static void test_cc_cubic(void)
{
struct cb_opts cb_opts = {
@@ -637,6 +647,8 @@ void test_bpf_tcp_ca(void)
test_link_replace();
if (test__start_subtest("tcp_ca_kfunc"))
test_tcp_ca_kfunc();
+ if (test__start_subtest("untrusted_btf_write"))
+ test_untrusted_btf_write();
if (test__start_subtest("cc_cubic"))
test_cc_cubic();
if (test__start_subtest("dctcp_autoattach_map"))
diff --git a/tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c b/tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c
new file mode 100644
index 000000000000..eda4697aac80
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "bpf_tracing_net.h"
+#include <bpf/bpf_core_read.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+SEC("struct_ops")
+void BPF_PROG(untrusted_btf_write_init, struct sock *sk)
+{
+ struct tcp_sock *tp;
+ int v = 1;
+ void *p;
+
+ p = bpf_rdonly_cast(&v, 0);
+ tp = bpf_rdonly_cast(p, bpf_core_type_id_kernel(struct tcp_sock));
+ tp->snd_cwnd = 1;
+}
+
+SEC(".struct_ops")
+struct tcp_congestion_ops untrusted_btf_write = {
+ .init = (void *)untrusted_btf_write_init,
+ .name = "bpf_ro_btf",
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes
2026-07-08 3:07 [PATCH bpf-next v2 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
2026-07-08 3:07 ` [PATCH bpf-next v2 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
2026-07-08 3:07 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
@ 2026-07-08 7:40 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-07-08 7:40 UTC (permalink / raw)
To: Kumar Kartikeya Dwivedi
Cc: bpf, ast, andrii, daniel, eddyz87, emil, kkd, kernel-team
Hello:
This series was applied to bpf/bpf-next.git (master)
by Eduard Zingerman <eddyz87@gmail.com>:
On Wed, 8 Jul 2026 05:07:49 +0200 you wrote:
> When using custom btf_struct_access() callbacks, we miss rejecting
> unstrusted BTF pointer writes. Fix and add a selftest for coverage.
>
> Changelog:
> ----------
> v1 -> v2
> v1: https://lore.kernel.org/bpf/20260707190214.1997705-1-memxor@gmail.com
>
> [...]
Here is the summary with links:
- [bpf-next,v2,1/2] bpf: Reject writes through untrusted BTF pointers
https://git.kernel.org/bpf/bpf-next/c/ac65c710cc64
- [bpf-next,v2,2/2] selftests/bpf: Add untrusted BTF write regression
https://git.kernel.org/bpf/bpf-next/c/9eab4790f11f
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] 4+ messages in thread