BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next v1 0/2] Fix for untrusted BTF pointer writes
@ 2026-07-07 19:02 Kumar Kartikeya Dwivedi
  2026-07-07 19:02 ` [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
  2026-07-07 19:02 ` [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
  0 siblings, 2 replies; 8+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-07 19:02 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team

When using custom btf_struct_access() callbacks, we miss rejecting
unstrusted BTF pointer writes. Fix and add a selftest for coverage.

Kumar Kartikeya Dwivedi (1):
  selftests/bpf: Add untrusted BTF write regression

Nicholas Dudar (1):
  bpf: Reject writes through untrusted BTF pointers

 kernel/bpf/verifier.c                         |  8 ++++--
 .../selftests/bpf/prog_tests/bpf_tcp_ca.c     | 12 +++++++++
 .../bpf/progs/tcp_ca_untrusted_btf_write.c    | 26 +++++++++++++++++++
 3 files changed, 44 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c


base-commit: f425a0443b7f0221a4b34f6acc0c2924bf5877f2
-- 
2.53.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers
  2026-07-07 19:02 [PATCH bpf-next v1 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
@ 2026-07-07 19:02 ` Kumar Kartikeya Dwivedi
  2026-07-07 19:48   ` bot+bpf-ci
  2026-07-07 22:10   ` Amery Hung
  2026-07-07 19:02 ` [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
  1 sibling, 2 replies; 8+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-07 19:02 UTC (permalink / raw)
  To: bpf
  Cc: 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.

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 3193b473762b..7cf555a7026c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5813,6 +5813,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");
@@ -5825,8 +5830,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] 8+ messages in thread

* [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression
  2026-07-07 19:02 [PATCH bpf-next v1 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
  2026-07-07 19:02 ` [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
@ 2026-07-07 19:02 ` Kumar Kartikeya Dwivedi
  2026-07-07 22:31   ` Amery Hung
  1 sibling, 1 reply; 8+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-07 19:02 UTC (permalink / raw)
  To: bpf
  Cc: 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.

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] 8+ messages in thread

* Re: [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers
  2026-07-07 19:02 ` [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
@ 2026-07-07 19:48   ` bot+bpf-ci
  2026-07-07 22:10   ` Amery Hung
  1 sibling, 0 replies; 8+ messages in thread
From: bot+bpf-ci @ 2026-07-07 19:48 UTC (permalink / raw)
  To: memxor, bpf
  Cc: main.kalliope, ast, andrii, daniel, eddyz87, emil, kkd,
	kernel-team, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 1250 bytes --]

> 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.
>
> Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>

This fixes a write path that bypassed the read-only policy for untrusted
BTF pointers, but there is no Fixes: tag.

The write-dispatch branch that took precedence over the untrusted
read-only check in check_ptr_to_btf_access(), along with the "but not for
untrusted PTR_TO_BTF_ID | MEM_ALLOC" comment that this patch removes, was
added when program allocated objects support was introduced.

Should this include:

  Fixes: 282de143ead9 ("bpf: Introduce allocated objects support")


---
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/28892378159

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers
  2026-07-07 19:02 ` [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
  2026-07-07 19:48   ` bot+bpf-ci
@ 2026-07-07 22:10   ` Amery Hung
  1 sibling, 0 replies; 8+ messages in thread
From: Amery Hung @ 2026-07-07 22:10 UTC (permalink / raw)
  To: Kumar Kartikeya Dwivedi
  Cc: bpf, Nicholas Dudar, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Emil Tsalapatis, kkd,
	kernel-team

On Tue, Jul 7, 2026 at 12:02 PM Kumar Kartikeya Dwivedi
<memxor@gmail.com> wrote:
>
> 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.
>
> Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>

Reviewed-by: Amery Hung <ameryhung@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 3193b473762b..7cf555a7026c 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -5813,6 +5813,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");
> @@ -5825,8 +5830,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	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression
  2026-07-07 19:02 ` [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
@ 2026-07-07 22:31   ` Amery Hung
  2026-07-07 22:36     ` Kumar Kartikeya Dwivedi
  0 siblings, 1 reply; 8+ messages in thread
From: Amery Hung @ 2026-07-07 22:31 UTC (permalink / raw)
  To: Kumar Kartikeya Dwivedi
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team

On Tue, Jul 7, 2026 at 12:02 PM Kumar Kartikeya Dwivedi
<memxor@gmail.com> wrote:
>
> 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.
>
> 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));

Do we need two bpf_rdonly_cast()? I tested the following and it also works:

        tp = bpf_rdonly_cast(&v, 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	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression
  2026-07-07 22:31   ` Amery Hung
@ 2026-07-07 22:36     ` Kumar Kartikeya Dwivedi
  2026-07-07 22:58       ` Amery Hung
  0 siblings, 1 reply; 8+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-07 22:36 UTC (permalink / raw)
  To: Amery Hung, Kumar Kartikeya Dwivedi
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team

On Wed Jul 8, 2026 at 12:31 AM CEST, Amery Hung wrote:
> On Tue, Jul 7, 2026 at 12:02 PM Kumar Kartikeya Dwivedi
> <memxor@gmail.com> wrote:
>>
>> 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.
>>
>> 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));
>
> Do we need two bpf_rdonly_cast()? I tested the following and it also works:
>

Yeah, single case works too, I mostly kept these two because of the original
report.

>         tp = bpf_rdonly_cast(&v, 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	[flat|nested] 8+ messages in thread

* Re: [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression
  2026-07-07 22:36     ` Kumar Kartikeya Dwivedi
@ 2026-07-07 22:58       ` Amery Hung
  0 siblings, 0 replies; 8+ messages in thread
From: Amery Hung @ 2026-07-07 22:58 UTC (permalink / raw)
  To: Kumar Kartikeya Dwivedi
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team

On Tue, Jul 7, 2026 at 3:36 PM Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
>
> On Wed Jul 8, 2026 at 12:31 AM CEST, Amery Hung wrote:
> > On Tue, Jul 7, 2026 at 12:02 PM Kumar Kartikeya Dwivedi
> > <memxor@gmail.com> wrote:
> >>
> >> 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.
> >>
> >> 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));
> >
> > Do we need two bpf_rdonly_cast()? I tested the following and it also works:
> >
>
> Yeah, single case works too, I mostly kept these two because of the original
> report.

I see. I was wondering whether the first cast has some special
purposes. Single cast reads a bit cleaner to me, but no strong
preference.

Reviewed-by: Amery Hung <ameryhung@gmail.com>

>
> >         tp = bpf_rdonly_cast(&v, 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	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-07-07 22:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 19:02 [PATCH bpf-next v1 0/2] Fix for untrusted BTF pointer writes Kumar Kartikeya Dwivedi
2026-07-07 19:02 ` [PATCH bpf-next v1 1/2] bpf: Reject writes through untrusted BTF pointers Kumar Kartikeya Dwivedi
2026-07-07 19:48   ` bot+bpf-ci
2026-07-07 22:10   ` Amery Hung
2026-07-07 19:02 ` [PATCH bpf-next v1 2/2] selftests/bpf: Add untrusted BTF write regression Kumar Kartikeya Dwivedi
2026-07-07 22:31   ` Amery Hung
2026-07-07 22:36     ` Kumar Kartikeya Dwivedi
2026-07-07 22:58       ` Amery Hung

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox