AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/08 13:35 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "check_ptr_to_btf_access"
  ],
  "Reasoning": "The patch modifies the BPF verifier to prevent writes to PTR_UNTRUSTED pointers, which is a functional change in core BPF logic.",
  "WorthFuzzing": true
}

1/1 2026/07/08 13:35 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 6fe43ca528feedc3e03642debd8dabc77ae8fb02\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Jul 8 13:35:22 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c\nindex 51f7965d42e324..4f42b4e929ad39 100644\n--- a/kernel/bpf/verifier.c\n+++ b/kernel/bpf/verifier.c\n@@ -5790,6 +5790,11 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,\n \t\treturn -EACCES;\n \t}\n \n+\tif (atype != BPF_READ \u0026\u0026 (type_flag(reg-\u003etype) \u0026 PTR_UNTRUSTED)) {\n+\t\tverbose(env, \"only read is supported\\n\");\n+\t\treturn -EACCES;\n+\t}\n+\n \tif (env-\u003eops-\u003ebtf_struct_access \u0026\u0026 !type_is_alloc(reg-\u003etype) \u0026\u0026 atype == BPF_WRITE) {\n \t\tif (!btf_is_kernel(reg-\u003ebtf)) {\n \t\t\tverifier_bug(env, \"reg-\u003ebtf must be kernel btf\");\n@@ -5802,8 +5807,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,\n \t\t\t\treg_arg_name(env, argno), tname, off, size);\n \t} else {\n \t\t/* Writes are permitted with default btf_struct_access for\n-\t\t * program allocated objects (which always have id \u003e 0),\n-\t\t * but not for untrusted PTR_TO_BTF_ID | MEM_ALLOC.\n+\t\t * program allocated objects (which always have id \u003e 0).\n \t\t */\n \t\tif (atype != BPF_READ \u0026\u0026 !type_is_ptr_alloc_obj(reg-\u003etype)) {\n \t\t\tverbose(env, \"only read is supported\\n\");\ndiff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c\nindex fe30181e63367d..eb05fc82f81ba6 100644\n--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c\n+++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c\n@@ -14,6 +14,7 @@\n #include \"tcp_ca_incompl_cong_ops.skel.h\"\n #include \"tcp_ca_unsupp_cong_op.skel.h\"\n #include \"tcp_ca_kfunc.skel.h\"\n+#include \"tcp_ca_untrusted_btf_write.skel.h\"\n #include \"bpf_cc_cubic.skel.h\"\n \n static const unsigned int total_bytes = 10 * 1024 * 1024;\n@@ -579,6 +580,15 @@ static void test_tcp_ca_kfunc(void)\n \ttcp_ca_kfunc__destroy(skel);\n }\n \n+static void test_untrusted_btf_write(void)\n+{\n+\tstruct tcp_ca_untrusted_btf_write *skel;\n+\n+\tskel = tcp_ca_untrusted_btf_write__open_and_load();\n+\tASSERT_ERR_PTR(skel, \"tcp_ca_untrusted_btf_write__open_and_load\");\n+\ttcp_ca_untrusted_btf_write__destroy(skel);\n+}\n+\n static void test_cc_cubic(void)\n {\n \tstruct cb_opts cb_opts = {\n@@ -637,6 +647,8 @@ void test_bpf_tcp_ca(void)\n \t\ttest_link_replace();\n \tif (test__start_subtest(\"tcp_ca_kfunc\"))\n \t\ttest_tcp_ca_kfunc();\n+\tif (test__start_subtest(\"untrusted_btf_write\"))\n+\t\ttest_untrusted_btf_write();\n \tif (test__start_subtest(\"cc_cubic\"))\n \t\ttest_cc_cubic();\n \tif (test__start_subtest(\"dctcp_autoattach_map\"))\ndiff --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\nnew file mode 100644\nindex 00000000000000..eda4697aac80b6\n--- /dev/null\n+++ b/tools/testing/selftests/bpf/progs/tcp_ca_untrusted_btf_write.c\n@@ -0,0 +1,26 @@\n+// SPDX-License-Identifier: GPL-2.0\n+\n+#include \"bpf_tracing_net.h\"\n+#include \u003cbpf/bpf_core_read.h\u003e\n+#include \u003cbpf/bpf_helpers.h\u003e\n+#include \u003cbpf/bpf_tracing.h\u003e\n+\n+char _license[] SEC(\"license\") = \"GPL\";\n+\n+SEC(\"struct_ops\")\n+void BPF_PROG(untrusted_btf_write_init, struct sock *sk)\n+{\n+\tstruct tcp_sock *tp;\n+\tint v = 1;\n+\tvoid *p;\n+\n+\tp = bpf_rdonly_cast(\u0026v, 0);\n+\ttp = bpf_rdonly_cast(p, bpf_core_type_id_kernel(struct tcp_sock));\n+\ttp-\u003esnd_cwnd = 1;\n+}\n+\n+SEC(\".struct_ops\")\n+struct tcp_congestion_ops untrusted_btf_write = {\n+\t.init = (void *)untrusted_btf_write_init,\n+\t.name = \"bpf_ro_btf\",\n+};\n"
}

2/1 2026/07/08 13:35 agent patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "check_ptr_to_btf_access"
  ],
  "Reasoning": "The patch modifies the BPF verifier to prevent writes to PTR_UNTRUSTED pointers, which is a functional change in core BPF logic.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. List them in the EnableConfigs output array,
   and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 6fe43ca528feedc3e03642debd8dabc77ae8fb02
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Jul 8 13:35:22 2026 +0000

    syz-cluster: applied patch under review

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 51f7965d42e324..4f42b4e929ad39 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");
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 fe30181e63367d..eb05fc82f81ba6 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 00000000000000..eda4697aac80b6
--- /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",
+};

3/2 2026/07/08 13:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 3117
							output: 81
							thoughts: 666
						

Thoughts:
**Analyzing a BPF Verifier Patch**

Okay, so I've got a patch here that's making a specific change within the BPF verifier, specifically in `kernel/bpf/verifier.c`. This is something I need to understand thoroughly. It looks like the change focuses on `check_ptr_to_btf_access`, a critical function for verifying BPF program access to BTF-based data. The core of this patch introduces a check: it now disallows writes to pointers marked as `PTR_UNTRUSTED`. My initial thought is that this is a solid security enhancement – preventing untrusted code from modifying potentially sensitive memory regions is always a good thing.

Functionally, this is a change that directly impacts the BPF verifier's behavior. The current verifier logic now permits only reading from these untrusted pointers. Given this change, it *absolutely* warrants fuzzing. We need to explore potential edge cases and ensure no new vulnerabilities are introduced through this new check, or that we haven't inadvertently broken anything that was previously valid.

My next step is to nail down the relevant configurations.  `CONFIG_BPF_SYSCALL` is the obvious one, and I'll confirm that it's generally enabled. Beyond that, I need to make sure I'm not missing any obscure configs that might also affect the verifier's behavior.  Then, I'll zero in on `check_ptr_to_btf_access` as the key focus symbol for our fuzzing efforts.  It's the heart of this change.

Therefore, for my fuzzing configuration I'll need to enable `CONFIG_BPF_SYSCALL` and define `check_ptr_to_btf_access` as the focus symbol, because this is an important functional change to the verifier's core logic.  I'd absolutely mark this as "worth fuzzing," given its impact on security and data access.



4/2 2026/07/08 13:35 tool set-results
0m Args:
{
  "EnableConfigs": [
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "check_ptr_to_btf_access"
  ],
  "Reasoning": "The patch modifies the BPF verifier to prevent writes to PTR_UNTRUSTED pointers, which is a functional change in core BPF logic.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "check_ptr_to_btf_access"
  ],
  "Reasoning": "The patch modifies the BPF verifier to prevent writes to PTR_UNTRUSTED pointers, which is a functional change in core BPF logic.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)