AI Trajectory


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

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL",
    "SMP"
  ],
  "FocusSymbols": [
    "bpf_do_misc_fixups",
    "check_map_prog_compatibility",
    "__add_used_map"
  ],
  "Reasoning": "The patch modifies the BPF verifier to force JIT compilation for programs that use per-CPU maps, specific BPF helpers (bpf_get_smp_processor_id, bpf_get_current_task, bpf_get_current_task_btf), arena maps, and instruction array maps. This is a functional change in the core BPF verifier logic that should be fuzzed to ensure it correctly enforces JIT requirements and doesn't introduce regressions or bypasses.",
  "WorthFuzzing": true
}

1/1 2026/07/15 21:35 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 3592969756711d6f592edf6a13b6fc652e48532b\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Jul 15 21:35:06 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/include/linux/bpf.h b/include/linux/bpf.h\nindex 31181e0c2b801b..d9542127dfdfc0 100644\n--- a/include/linux/bpf.h\n+++ b/include/linux/bpf.h\n@@ -4163,7 +4163,7 @@ bpf_prog_update_insn_ptrs(struct bpf_prog *prog, u32 *offsets, void *image)\n }\n #endif\n \n-static inline bool bpf_map_supports_cpu_flags(enum bpf_map_type map_type)\n+static inline bool bpf_map_is_percpu_map(enum bpf_map_type map_type)\n {\n \tswitch (map_type) {\n \tcase BPF_MAP_TYPE_PERCPU_ARRAY:\n@@ -4190,7 +4190,7 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all\n \t\treturn -EINVAL;\n \n \tif (flags \u0026 (BPF_F_CPU | BPF_F_ALL_CPUS)) {\n-\t\tif (!bpf_map_supports_cpu_flags(map-\u003emap_type))\n+\t\tif (!bpf_map_is_percpu_map(map-\u003emap_type))\n \t\t\treturn -EINVAL;\n \t\tif ((flags \u0026 BPF_F_CPU) \u0026\u0026 (flags \u0026 BPF_F_ALL_CPUS))\n \t\t\treturn -EINVAL;\ndiff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c\nindex d3be972714b22c..a0bddada7964e7 100644\n--- a/kernel/bpf/fixups.c\n+++ b/kernel/bpf/fixups.c\n@@ -2008,6 +2008,9 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)\n \t\t\t\t\treturn -EFAULT;\n \t\t\t\t}\n \n+\t\t\t\tif (bpf_map_is_percpu_map(map_ptr-\u003emap_type))\n+\t\t\t\t\tprog-\u003ejit_required = true;\n+\n \t\t\t\tnew_prog = bpf_patch_insn_data(env, i + delta,\n \t\t\t\t\t\t\t       insn_buf, cnt);\n \t\t\t\tif (!new_prog)\n@@ -2112,6 +2115,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)\n \t\t\t * way, it's fine to back out this inlining logic\n \t\t\t */\n #ifdef CONFIG_SMP\n+\t\t\tprog-\u003ejit_required = true;\n \t\t\tinsn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)\u0026cpu_number);\n \t\t\tinsn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);\n \t\t\tinsn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0);\n@@ -2133,6 +2137,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)\n \t\t/* Implement bpf_get_current_task() and bpf_get_current_task_btf() inline. */\n \t\tif ((insn-\u003eimm == BPF_FUNC_get_current_task || insn-\u003eimm == BPF_FUNC_get_current_task_btf) \u0026\u0026\n \t\t    bpf_verifier_inlines_helper_call(env, insn-\u003eimm)) {\n+\t\t\tprog-\u003ejit_required = true;\n \t\t\tinsn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)\u0026current_task);\n \t\t\tinsn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);\n \t\t\tinsn_buf[2] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0);\ndiff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c\nindex de816063ae63d0..e2ef7836b7b507 100644\n--- a/kernel/bpf/verifier.c\n+++ b/kernel/bpf/verifier.c\n@@ -17873,6 +17873,7 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,\n \t\t\treturn -EOPNOTSUPP;\n \t\t}\n \t\tenv-\u003eprog-\u003eaux-\u003earena = (void *)map;\n+\t\tenv-\u003eprog-\u003ejit_required = true;\n \t\tif (!bpf_arena_get_user_vm_start(env-\u003eprog-\u003eaux-\u003earena)) {\n \t\t\tverbose(env, \"arena's user address must be set via map_extra or mmap()\\n\");\n \t\t\treturn -EINVAL;\n@@ -17926,6 +17927,7 @@ static int __add_used_map(struct bpf_verifier_env *env, struct bpf_map *map)\n \t\t\treturn err;\n \t\t}\n \t\tenv-\u003einsn_array_maps[env-\u003einsn_array_map_cnt++] = map;\n+\t\tenv-\u003eprog-\u003ejit_required = true;\n \t}\n \n \treturn env-\u003eused_map_cnt - 1;\n"
}

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

Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL",
    "SMP"
  ],
  "FocusSymbols": [
    "bpf_do_misc_fixups",
    "check_map_prog_compatibility",
    "__add_used_map"
  ],
  "Reasoning": "The patch modifies the BPF verifier to force JIT compilation for programs that use per-CPU maps, specific BPF helpers (bpf_get_smp_processor_id, bpf_get_current_task, bpf_get_current_task_btf), arena maps, and instruction array maps. This is a functional change in the core BPF verifier logic that should be fuzzed to ensure it correctly enforces JIT requirements and doesn't introduce regressions or bypasses.",
  "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 3592969756711d6f592edf6a13b6fc652e48532b
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Jul 15 21:35:06 2026 +0000

    syz-cluster: applied patch under review

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 31181e0c2b801b..d9542127dfdfc0 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -4163,7 +4163,7 @@ bpf_prog_update_insn_ptrs(struct bpf_prog *prog, u32 *offsets, void *image)
 }
 #endif
 
-static inline bool bpf_map_supports_cpu_flags(enum bpf_map_type map_type)
+static inline bool bpf_map_is_percpu_map(enum bpf_map_type map_type)
 {
 	switch (map_type) {
 	case BPF_MAP_TYPE_PERCPU_ARRAY:
@@ -4190,7 +4190,7 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all
 		return -EINVAL;
 
 	if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS)) {
-		if (!bpf_map_supports_cpu_flags(map->map_type))
+		if (!bpf_map_is_percpu_map(map->map_type))
 			return -EINVAL;
 		if ((flags & BPF_F_CPU) && (flags & BPF_F_ALL_CPUS))
 			return -EINVAL;
diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
index d3be972714b22c..a0bddada7964e7 100644
--- a/kernel/bpf/fixups.c
+++ b/kernel/bpf/fixups.c
@@ -2008,6 +2008,9 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
 					return -EFAULT;
 				}
 
+				if (bpf_map_is_percpu_map(map_ptr->map_type))
+					prog->jit_required = true;
+
 				new_prog = bpf_patch_insn_data(env, i + delta,
 							       insn_buf, cnt);
 				if (!new_prog)
@@ -2112,6 +2115,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
 			 * way, it's fine to back out this inlining logic
 			 */
 #ifdef CONFIG_SMP
+			prog->jit_required = true;
 			insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&cpu_number);
 			insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);
 			insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0);
@@ -2133,6 +2137,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
 		/* Implement bpf_get_current_task() and bpf_get_current_task_btf() inline. */
 		if ((insn->imm == BPF_FUNC_get_current_task || insn->imm == BPF_FUNC_get_current_task_btf) &&
 		    bpf_verifier_inlines_helper_call(env, insn->imm)) {
+			prog->jit_required = true;
 			insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&current_task);
 			insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);
 			insn_buf[2] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index de816063ae63d0..e2ef7836b7b507 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -17873,6 +17873,7 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
 			return -EOPNOTSUPP;
 		}
 		env->prog->aux->arena = (void *)map;
+		env->prog->jit_required = true;
 		if (!bpf_arena_get_user_vm_start(env->prog->aux->arena)) {
 			verbose(env, "arena's user address must be set via map_extra or mmap()\n");
 			return -EINVAL;
@@ -17926,6 +17927,7 @@ static int __add_used_map(struct bpf_verifier_env *env, struct bpf_map *map)
 			return err;
 		}
 		env->insn_array_maps[env->insn_array_map_cnt++] = map;
+		env->prog->jit_required = true;
 	}
 
 	return env->used_map_cnt - 1;

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

Args:
null

Results:
null

Tokens:
							input: 3036
							output: 23
							thoughts: 293
						

Thoughts:
**Analyzing a BPF Fixup Patch**

Okay, so I'm looking at this patch and my initial impression is it's a focused change within the BPF subsystem, touching upon the verifier and fixups, specifically. It's modifying a few key files: `include/linux/bpf.h`, `kernel/bpf/fixups.c`, and `kernel/bpf/verifier.c`. The core of the change seems to involve renaming `bpf_map_supports_cpu_flags` to `bpf_map_is_percpu_map`, which feels like a more descriptive name, a good move really.

The crucial bit, though, is the introduction of `prog->jit_required = true` in several spots within `bpf_do_misc_fixups`, and `check_map_prog_compatibility` and `__add_used_map`. Right, so this means that programs *relying* on this modified logic will now *require* JIT compilation. This is a pretty significant constraint as it impacts performance and potential compatibility concerns.

The affected scenarios are pretty clear: any program utilizing per-CPU maps, `bpf_get_smp_processor_id`, `bpf_get_current_task`, `bpf_get_current_task_btf`, arena maps, and instruction array maps. It makes sense, these features often involve dynamic or per-CPU data access that benefits a JIT.

Now, I need to understand the implications better. BPF is enabled via `CONFIG_BPF_SYSCALL`, that's the base requirement. I need to dig deeper into the configs surrounding these functions: `bpf_do_misc_fixups`, `check_map_prog_compatibility`, and `__add_used_map`. I'm going to leverage `default_api:grepper` to see if there are any specific configs associated with these functions that might shed light on how they're utilized elsewhere, and what the dependencies or implications are. Gotta see if there are any config dependencies, or corner cases in the system that'll be affected. It's time to dig into the details.



4/2 2026/07/15 21:35 tool grepper
0m Args:
{
  "Expression": "bpf_do_misc_fixups"
}

Results:
{
  "Output": "include/linux/bpf_verifier.h=1656=int bpf_fixup_call_args(struct bpf_verifier_env *env);\ninclude/linux/bpf_verifier.h:1657:int bpf_do_misc_fixups(struct bpf_verifier_env *env);\ninclude/linux/bpf_verifier.h-1658-\n--\nkernel/bpf/fixups.c=1451=static int add_hidden_subprog(struct bpf_verifier_env *env, struct bpf_insn *patch, int len)\n--\nkernel/bpf/fixups.c-1479- */\nkernel/bpf/fixups.c:1480:int bpf_do_misc_fixups(struct bpf_verifier_env *env)\nkernel/bpf/fixups.c-1481-{\n--\nkernel/bpf/verifier.c=20004=int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,\n--\nkernel/bpf/verifier.c-20216-\tif (ret == 0)\nkernel/bpf/verifier.c:20217:\t\tret = bpf_do_misc_fixups(env);\nkernel/bpf/verifier.c-20218-\n"
}

5/2 2026/07/15 21:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 4162
							output: 20
							thoughts: 50
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own:

**Analyzing this BPF Patch**

Alright, so the patch is going straight into the core BPF verifier, that's important to note. And a quick reminder that `CONFIG_BPF_SYSCALL` is the crucial configuration option here, so I'll keep that in mind as I delve further. My immediate next step is to examine the impact on `__add_used_map` and the function `check_map_prog_compatibility`. These are key areas, especially in relation to map interactions, and this patch will undoubtedly have some ripple effects there that I'll need to understand. I will have to ensure that all of the map interactions and verifier checks are still appropriate.



6/2 2026/07/15 21:35 tool grepper
0m Args:
{
  "Expression": "__add_used_map"
}

Results:
{
  "Output": "kernel/bpf/verifier.c=17778=static int check_map_prog_compatibility(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c-17885-\nkernel/bpf/verifier.c:17886:static int __add_used_map(struct bpf_verifier_env *env, struct bpf_map *map)\nkernel/bpf/verifier.c-17887-{\n--\nkernel/bpf/verifier.c=17940=static int add_used_map(struct bpf_verifier_env *env, int fd)\n--\nkernel/bpf/verifier.c-17950-\nkernel/bpf/verifier.c:17951:\treturn __add_used_map(env, map);\nkernel/bpf/verifier.c-17952-}\n--\nkernel/bpf/verifier.c=17954=static int fd_array_get_map_idx_continuous(struct bpf_verifier_env *env, u32 idx)\n--\nkernel/bpf/verifier.c-17967-\t}\nkernel/bpf/verifier.c:17968:\treturn __add_used_map(env, map);\nkernel/bpf/verifier.c-17969-}\n--\nkernel/bpf/verifier.c=19561=static int add_fd_from_fd_array(struct bpf_verifier_env *env, u32 idx, int fd)\n--\nkernel/bpf/verifier.c-19569-\tif (!IS_ERR(map)) {\nkernel/bpf/verifier.c:19570:\t\terr = __add_used_map(env, map);\nkernel/bpf/verifier.c-19571-\t\tif (err \u003c 0)\n--\nkernel/bpf/verifier.c-19595- * the number of distinct maps and BTFs a program can bind is enforced when\nkernel/bpf/verifier.c:19596: * each entry is resolved by __add_used_map() and __add_used_btf().\nkernel/bpf/verifier.c-19597- */\n"
}

7/2 2026/07/15 21:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 4953
							output: 17
							thoughts: 313
						

Thoughts:
**Analyzing the JIT Forcing Patch**

Okay, so this patch is essentially forcing the Just-In-Time (JIT) compiler for specific BPF (Berkeley Packet Filter) programs. The key here is this line: `prog->jit_required = true;` This is a clear functional change, so I need to understand its implications.

My initial focus is on the functions that are modified or potentially impacted by this change: `bpf_do_misc_fixups`, `check_map_prog_compatibility`, and `__add_used_map`. These seem to be the core of the adjustment. `bpf_do_misc_fixups` is called for every BPF program loaded, which makes it a potentially hot spot. However, it's called during verification, not the execution path, so that's good. `check_map_prog_compatibility` and `__add_used_map` are also verifier functions, so they are not directly in the program execution.

I need to confirm if `bpf_do_misc_fixups` is the correct focus. It's called during `bpf_check`, which is the main entry point for the verifier, so it should be. `check_map_prog_compatibility` and `__add_used_map` will also be good to review.

Next, I need to check the configurations. I know `CONFIG_BPF_SYSCALL` is a hard requirement for BPF. The patch mentions `CONFIG_SMP`, which is common, but it's important to keep track of its interaction. I suspect `CONFIG_BPF_JIT` is probably required to properly test the JIT enforcement. The `jit_required` might be designed to reject the program if the JIT is not enabled or requested.

Finally, I need to thoroughly examine the usage of `jit_required` to fully grasp the scope and effects of this change.



8/2 2026/07/15 21:35 tool grepper
0m Args:
{
  "Expression": "jit_required"
}

Results:
{
  "Output": "include/linux/bpf.h=1865=struct bpf_prog {\n--\ninclude/linux/bpf.h-1868-\t\t\t\tjit_requested:1,/* archs need to JIT the prog */\ninclude/linux/bpf.h:1869:\t\t\t\tjit_required:1,\t/* program strictly requires JIT compiler */\ninclude/linux/bpf.h-1870-\t\t\t\tgpl_compatible:1, /* Is filter GPL compatible? */\n--\nkernel/bpf/core.c=100=struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flags)\n--\nkernel/bpf/core.c-128-\tfp-\u003ejit_requested = ebpf_jit_enabled();\nkernel/bpf/core.c:129:\tfp-\u003ejit_required = IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON);\nkernel/bpf/core.c-130-\tfp-\u003eblinding_requested = bpf_jit_blinding_enabled(fp);\n--\nkernel/bpf/core.c=2668=struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, struct bpf_prog *fp,\n--\nkernel/bpf/core.c-2673-\t */\nkernel/bpf/core.c:2674:\tbool jit_needed = fp-\u003ejit_required;\nkernel/bpf/core.c-2675-\n--\nkernel/bpf/fixups.c=1376=int bpf_fixup_call_args(struct bpf_verifier_env *env)\n--\nkernel/bpf/fixups.c-1405-#ifndef CONFIG_BPF_JIT_ALWAYS_ON\nkernel/bpf/fixups.c:1406:\tif (prog-\u003ejit_required) {\nkernel/bpf/fixups.c-1407-\t\tverbose(env, \"program requires BPF JIT compiler but it is not available\\n\");\n--\nkernel/bpf/fixups.c=1480=int bpf_do_misc_fixups(struct bpf_verifier_env *env)\n--\nkernel/bpf/fixups.c-1843-\t\tif (bpf_jit_inlines_helper_call(insn-\u003eimm)) {\nkernel/bpf/fixups.c:1844:\t\t\tprog-\u003ejit_required = 1;\nkernel/bpf/fixups.c-1845-\t\t\tgoto next_insn;\n--\nkernel/bpf/fixups.c-2011-\t\t\t\tif (bpf_map_is_percpu_map(map_ptr-\u003emap_type))\nkernel/bpf/fixups.c:2012:\t\t\t\t\tprog-\u003ejit_required = true;\nkernel/bpf/fixups.c-2013-\n--\nkernel/bpf/fixups.c-2117-#ifdef CONFIG_SMP\nkernel/bpf/fixups.c:2118:\t\t\tprog-\u003ejit_required = true;\nkernel/bpf/fixups.c-2119-\t\t\tinsn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)\u0026cpu_number);\n--\nkernel/bpf/fixups.c-2139-\t\t    bpf_verifier_inlines_helper_call(env, insn-\u003eimm)) {\nkernel/bpf/fixups.c:2140:\t\t\tprog-\u003ejit_required = true;\nkernel/bpf/fixups.c-2141-\t\t\tinsn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)\u0026current_task);\n--\nkernel/bpf/verifier.c=2721=int bpf_add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, u16 offset)\n--\nkernel/bpf/verifier.c-2761-\nkernel/bpf/verifier.c:2762:\tenv-\u003eprog-\u003ejit_required = 1;\nkernel/bpf/verifier.c-2763-\n--\nkernel/bpf/verifier.c=17778=static int check_map_prog_compatibility(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c-17875-\t\tenv-\u003eprog-\u003eaux-\u003earena = (void *)map;\nkernel/bpf/verifier.c:17876:\t\tenv-\u003eprog-\u003ejit_required = true;\nkernel/bpf/verifier.c-17877-\t\tif (!bpf_arena_get_user_vm_start(env-\u003eprog-\u003eaux-\u003earena)) {\n--\nkernel/bpf/verifier.c=17886=static int __add_used_map(struct bpf_verifier_env *env, struct bpf_map *map)\n--\nkernel/bpf/verifier.c-17929-\t\tenv-\u003einsn_array_maps[env-\u003einsn_array_map_cnt++] = map;\nkernel/bpf/verifier.c:17930:\t\tenv-\u003eprog-\u003ejit_required = true;\nkernel/bpf/verifier.c-17931-\t}\n"
}

9/2 2026/07/15 21:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7021
							output: 23
							thoughts: 229
						

Thoughts:
**My Analysis of the BPF Patch**

Okay, so this patch is essentially forcing the JIT requirement to be active for any BPF program that uses per-CPU maps, specific BPF helper functions like `bpf_get_smp_processor_id`, or certain map types such as arena and instruction array maps. This is clearly a functional change, not just a performance tweak, and I need to understand the implications thoroughly.

My primary focus here needs to be the `bpf_do_misc_fixups`, `check_map_prog_compatibility`, and `__add_used_map` functions; I need to drill down into how they interact now, with this `jit_required` flag being set. I also need to keep `BPF_SYSCALL` and `SMP` configurations in mind as they'll likely play a role in this.

The immediate question is, what happens if the JIT isn't enabled? If `BPF_JIT` is disabled, the verifier *should* now reject the program outright, because `jit_required` is true but no JIT is available to meet that requirement. But wait, I recall `bpf_fixup_call_args` performing some checks! Does it already handle the case where `prog->jit_required` is set, and it would reject the program if `CONFIG_BPF_JIT_ALWAYS_ON` isn't set, and if there's no JIT available? I should go back and review the `bpf_fixup_call_args` function to confirm my understanding. It is vital to get the interaction of these parts correct.



10/2 2026/07/15 21:35 tool grepper
0m Args:
{
  "Expression": "bpf_fixup_call_args"
}

Results:
{
  "Output": "include/linux/bpf_verifier.h=1655=int bpf_jit_subprogs(struct bpf_verifier_env *env);\ninclude/linux/bpf_verifier.h:1656:int bpf_fixup_call_args(struct bpf_verifier_env *env);\ninclude/linux/bpf_verifier.h-1657-int bpf_do_misc_fixups(struct bpf_verifier_env *env);\n--\nkernel/bpf/fixups.c=1296=int bpf_jit_subprogs(struct bpf_verifier_env *env)\n--\nkernel/bpf/fixups.c-1375-\nkernel/bpf/fixups.c:1376:int bpf_fixup_call_args(struct bpf_verifier_env *env)\nkernel/bpf/fixups.c-1377-{\n--\nkernel/bpf/verifier.c=20004=int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,\n--\nkernel/bpf/verifier.c-20228-\tif (ret == 0)\nkernel/bpf/verifier.c:20229:\t\tret = bpf_fixup_call_args(env);\nkernel/bpf/verifier.c-20230-\n"
}

11/2 2026/07/15 21:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7979
							output: 38
							thoughts: 26
						

Thoughts:
Okay, let's dive into this. Here's my thought process on the matter:

**Analyzing `bpf_fixup_call_args` and `jit_required`**

Right, so I need to understand how the `jit_required` flag interacts with the call argument handling in the BPF world. My immediate focus is on the `bpf_fixup_call_args` function. I want to see precisely how it's used and what conditional logic is in place around that `jit_required` flag. I suspect this function might be the key to ensuring that JIT compilation is triggered appropriately when dealing with arguments that require it. I'm expecting to see conditions around optimization, potential register spills or loads, or maybe even function inlining decisions, all influenced by that `jit_required` signal. My goal is to map out the control flow and identify the exact points where `jit_required` is checked and acted upon. This could reveal some interesting performance implications.



12/2 2026/07/15 21:35 tool read-file
0m Args:
{
  "File": "kernel/bpf/fixups.c",
  "FirstLine": 1376,
  "LineCount": 50
}

Results:
{
  "Contents": "1376:\tint bpf_fixup_call_args(struct bpf_verifier_env *env)\n1377:\t{\n1378:\t#ifndef CONFIG_BPF_JIT_ALWAYS_ON\n1379:\t\tstruct bpf_prog *prog = env-\u003eprog;\n1380:\t\tstruct bpf_insn *insn = prog-\u003einsnsi;\n1381:\t\tint depth;\n1382:\t#endif\n1383:\t\tint i, err = 0;\n1384:\t\n1385:\t\tfor (i = 0; i \u003c env-\u003esubprog_cnt; i++) {\n1386:\t\t\tstruct bpf_subprog_info *subprog = \u0026env-\u003esubprog_info[i];\n1387:\t\t\tu16 outgoing = subprog-\u003estack_arg_cnt - bpf_in_stack_arg_cnt(subprog);\n1388:\t\n1389:\t\t\tif (subprog-\u003emax_out_stack_arg_cnt \u003e outgoing) {\n1390:\t\t\t\tverbose(env,\n1391:\t\t\t\t\t\"func#%d writes %u stack arg slots, but calls only require %u\\n\",\n1392:\t\t\t\t\ti, subprog-\u003emax_out_stack_arg_cnt, outgoing);\n1393:\t\t\t\treturn -EINVAL;\n1394:\t\t\t}\n1395:\t\t}\n1396:\t\n1397:\t\tif (env-\u003eprog-\u003ejit_requested \u0026\u0026\n1398:\t\t    !bpf_prog_is_offloaded(env-\u003eprog-\u003eaux)) {\n1399:\t\t\terr = bpf_jit_subprogs(env);\n1400:\t\t\tif (err == 0)\n1401:\t\t\t\treturn 0;\n1402:\t\t\tif (err == -EFAULT)\n1403:\t\t\t\treturn err;\n1404:\t\t}\n1405:\t#ifndef CONFIG_BPF_JIT_ALWAYS_ON\n1406:\t\tif (prog-\u003ejit_required) {\n1407:\t\t\tverbose(env, \"program requires BPF JIT compiler but it is not available\\n\");\n1408:\t\t\treturn -EINVAL;\n1409:\t\t}\n1410:\t\tfor (i = 0; i \u003c env-\u003esubprog_cnt; i++) {\n1411:\t\t\tif (bpf_in_stack_arg_cnt(\u0026env-\u003esubprog_info[i])) {\n1412:\t\t\t\tverbose(env, \"stack args are not supported in non-JITed programs\\n\");\n1413:\t\t\t\treturn -EINVAL;\n1414:\t\t\t}\n1415:\t\t}\n1416:\t\tif (env-\u003esubprog_cnt \u003e 1 \u0026\u0026 env-\u003eprog-\u003eaux-\u003etail_call_reachable) {\n1417:\t\t\t/* When JIT fails the progs with bpf2bpf calls and tail_calls\n1418:\t\t\t * have to be rejected, since interpreter doesn't support them yet.\n1419:\t\t\t */\n1420:\t\t\tverbose(env, \"tail_calls are not allowed in non-JITed programs with bpf-to-bpf calls\\n\");\n1421:\t\t\treturn -EINVAL;\n1422:\t\t}\n1423:\t\tfor (i = 0; i \u003c prog-\u003elen; i++, insn++) {\n1424:\t\t\tif (bpf_pseudo_func(insn)) {\n1425:\t\t\t\t/* When JIT fails the progs with callback calls\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 9147
							output: 178
							thoughts: 517
						

Thoughts:
**Analyzing BPF JIT Requirements and Fuzzing Strategy**

Okay, let's break this down. My initial thought is: the code's logic concerning BPF JIT requirements is based on `CONFIG_BPF_JIT_ALWAYS_ON` and `prog->jit_required`. If `CONFIG_BPF_JIT_ALWAYS_ON` isn't set, and `prog->jit_required` is true, the program is rejected. However, if `CONFIG_BPF_JIT_ALWAYS_ON` is set, then `prog->jit_required` defaults to true, and it *doesn't* reject it. The trickier part is when `CONFIG_BPF_JIT_ALWAYS_ON` *isn't* set, but `prog->jit_required` is true; in this case, it appears to rely on `bpf_jit_subprogs` succeeding. I see that `bpf_jit_subprogs` is called if `jit_requested` and returns 0 on success. If it fails or `jit_requested` is false, it proceeds into the `#ifndef CONFIG_BPF_JIT_ALWAYS_ON` block. So the conclusion here is that when `prog->jit_required` is true, the JIT *must* succeed.

To properly test this, I'd want to enable `BPF_JIT` and `BPF_JIT_ALWAYS_ON`, or simply `BPF_JIT`. Good news, syzbot already uses these, so I only need to note `BPF_SYSCALL` and `SMP` for my configuration.

Alright, now let's circle back to the patch itself. It's changing `bpf_map_supports_cpu_flags` to `bpf_map_is_percpu_map`, which looks innocuous, but in the context of the JIT, it could be significant. The patch is setting `prog->jit_required = true` in `bpf_do_misc_fixups` for percpu maps, `bpf_get_smp_processor_id`, `bpf_get_current_task`, `bpf_get_current_task_btf`. In `check_map_prog_compatibility`, it is setting `prog->jit_required = true` for arena maps. And in `__add_used_map` for instruction array maps. So this is definitely a functional change, especially around these map types and specific instructions.

This constitutes a functional change that warrants fuzzing, especially considering its relation to the JIT. My focus functions for fuzzing will be `bpf_do_misc_fixups`, `check_map_prog_compatibility`, and `__add_used_map`. The relevant config is `BPF_SYSCALL`.

Time to call `set-results`.



14/2 2026/07/15 21:35 tool set-results
0m Args:
{
  "EnableConfigs": [
    "BPF_SYSCALL",
    "SMP"
  ],
  "FocusSymbols": [
    "bpf_do_misc_fixups",
    "check_map_prog_compatibility",
    "__add_used_map"
  ],
  "Reasoning": "The patch modifies the BPF verifier to force JIT compilation for programs that use per-CPU maps, specific BPF helpers (bpf_get_smp_processor_id, bpf_get_current_task, bpf_get_current_task_btf), arena maps, and instruction array maps. This is a functional change in the core BPF verifier logic that should be fuzzed to ensure it correctly enforces JIT requirements and doesn't introduce regressions or bypasses.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "BPF_SYSCALL",
    "SMP"
  ],
  "FocusSymbols": [
    "bpf_do_misc_fixups",
    "check_map_prog_compatibility",
    "__add_used_map"
  ],
  "Reasoning": "The patch modifies the BPF verifier to force JIT compilation for programs that use per-CPU maps, specific BPF helpers (bpf_get_smp_processor_id, bpf_get_current_task, bpf_get_current_task_btf), arena maps, and instruction array maps. This is a functional change in the core BPF verifier logic that should be fuzzed to ensure it correctly enforces JIT requirements and doesn't introduce regressions or bypasses.",
  "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)