| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/19 12:09 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"BPF_EVENTS"
],
"FocusSymbols": [
"process_spin_lock",
"check_kfunc_args",
"check_map_prog_compatibility",
"check_kfunc_call"
],
"Reasoning": "The patch modifies the BPF verifier to change how tracing programs are restricted from using `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root`. It moves the restriction from map compatibility check to actual usage check, which is a functional change in the verifier logic that should be fuzzed.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/19 12:09 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit ae2c54095e6e30511ddaf02671f604a154585afe\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Jul 19 12:09:46 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c\nindex a78cdabf85607f..3e42705dd66805 100644\n--- a/kernel/bpf/verifier.c\n+++ b/kernel/bpf/verifier.c\n@@ -207,7 +207,7 @@ static int release_reference_nomark(struct bpf_verifier_state *state, int id);\n static int release_reference(struct bpf_verifier_env *env, int id);\n static void invalidate_non_owning_refs(struct bpf_verifier_env *env);\n static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env);\n-static bool is_tracing_prog_type(enum bpf_prog_type type);\n+static bool is_tracing_prog_type(struct bpf_prog *prog);\n static int ref_set_non_owning(struct bpf_verifier_env *env,\n \t\t\t struct bpf_reg_state *reg);\n static bool is_trusted_reg(struct bpf_verifier_env *env, const struct bpf_reg_state *reg);\n@@ -7081,6 +7081,12 @@ static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state\n \t\t\tval, lock_str, spin_lock_off);\n \t\treturn -EINVAL;\n \t}\n+\n+\tif (is_tracing_prog_type(env-\u003eprog) \u0026\u0026 !is_res_lock) {\n+\t\tverbose(env, \"tracing progs cannot use bpf_spin_lock yet\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n \tif (is_lock) {\n \t\tvoid *ptr;\n \t\tint type;\n@@ -12309,6 +12315,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me\n \t\t\t\tverbose(env, \"allocated object must be referenced\\n\");\n \t\t\t\treturn -EINVAL;\n \t\t\t}\n+\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\n+\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n \t\t\tret = process_kf_arg_ptr_to_list_head(env, reg, argno, meta);\n \t\t\tif (ret \u003c 0)\n \t\t\t\treturn ret;\n@@ -12325,6 +12335,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me\n \t\t\t\tverbose(env, \"allocated object must be referenced\\n\");\n \t\t\t\treturn -EINVAL;\n \t\t\t}\n+\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\n+\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n \t\t\tret = process_kf_arg_ptr_to_rbtree_root(env, reg, argno, meta);\n \t\t\tif (ret \u003c 0)\n \t\t\t\treturn ret;\n@@ -12958,7 +12972,6 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,\n \t\t\t int *insn_idx_p)\n {\n \tbool sleepable, rcu_lock, rcu_unlock, preempt_disable, preempt_enable;\n-\tenum bpf_prog_type prog_type = resolve_prog_type(env-\u003eprog);\n \tstruct bpf_reg_state *regs = cur_regs(env);\n \tconst char *func_name, *ptr_type_name;\n \tconst struct btf_type *t, *ptr_type;\n@@ -13036,10 +13049,8 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,\n \t\treturn err;\n \n \tif ((is_bpf_obj_drop_kfunc(meta.func_id) ||\n-\t is_bpf_percpu_obj_drop_kfunc(meta.func_id)) \u0026\u0026 (is_tracing_prog_type(prog_type) ||\n-\t /* is_tracing_prog_type() for now doesn't cover non-iterator tracing progs. */\n-\t (prog_type == BPF_PROG_TYPE_TRACING \u0026\u0026 env-\u003eprog-\u003eexpected_attach_type != BPF_TRACE_ITER\n-\t \u0026\u0026 !env-\u003eprog-\u003esleepable))) {\n+\t is_bpf_percpu_obj_drop_kfunc(meta.func_id)) \u0026\u0026 (is_tracing_prog_type(env-\u003eprog)\n+\t \u0026\u0026 !env-\u003eprog-\u003esleepable)) {\n \t\tstruct btf_struct_meta *struct_meta;\n \n \t\tstruct_meta = btf_find_struct_meta(meta.arg_btf, meta.arg_btf_id);\n@@ -17761,9 +17772,11 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,\n \treturn __add_used_btf(env, btf);\n }\n \n-static bool is_tracing_prog_type(enum bpf_prog_type type)\n+static bool is_tracing_prog_type(struct bpf_prog *prog)\n {\n-\tswitch (type) {\n+\tswitch (resolve_prog_type(prog)) {\n+\tcase BPF_PROG_TYPE_TRACING:\n+\t\treturn prog-\u003eexpected_attach_type != BPF_TRACE_ITER;\n \tcase BPF_PROG_TYPE_KPROBE:\n \tcase BPF_PROG_TYPE_TRACEPOINT:\n \tcase BPF_PROG_TYPE_PERF_EVENT:\n@@ -17794,26 +17807,19 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,\n \t\treturn -EACCES;\n \t}\n \n-\tif (btf_record_has_field(map-\u003erecord, BPF_LIST_HEAD) ||\n-\t btf_record_has_field(map-\u003erecord, BPF_RB_ROOT)) {\n-\t\tif (is_tracing_prog_type(prog_type)) {\n-\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\t}\n-\n \tif (btf_record_has_field(map-\u003erecord, BPF_SPIN_LOCK | BPF_RES_SPIN_LOCK)) {\n \t\tif (prog_type == BPF_PROG_TYPE_SOCKET_FILTER) {\n \t\t\tverbose(env, \"socket filter progs cannot use bpf_spin_lock yet\\n\");\n \t\t\treturn -EINVAL;\n \t\t}\n-\n-\t\tif (is_tracing_prog_type(prog_type)) {\n-\t\t\tverbose(env, \"tracing progs cannot use bpf_spin_lock yet\\n\");\n-\t\t\treturn -EINVAL;\n-\t\t}\n \t}\n \n+\t/*\n+\t * Restrictions on using BPF list,rbtree,spin_lock is checked later upon\n+\t * use, since rejecting accesing map containing them in programs is too\n+\t * conservative.\n+\t */\n+\n \tif ((bpf_prog_is_offloaded(prog-\u003eaux) || bpf_map_is_offloaded(map)) \u0026\u0026\n \t !bpf_offload_prog_map_match(prog, map)) {\n \t\tverbose(env, \"offload device mismatch between prog and map\\n\");\ndiff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c\nindex c3d133c6a00d40..702268422673a1 100644\n--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c\n+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c\n@@ -59,12 +59,12 @@ static struct {\n \tTEST(inner_map, pop_front)\n \tTEST(inner_map, pop_back)\n #undef TEST\n-\t{ \"map_compat_kprobe\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n-\t{ \"map_compat_kretprobe\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n+\t{ \"map_compat_kprobe\", \"calling kernel function bpf_list_push_front is not allowed\" },\n+\t{ \"map_compat_kretprobe\", \"calling kernel function bpf_list_push_front is not allowed\" },\n \t{ \"map_compat_tp\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n \t{ \"map_compat_perf\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n \t{ \"map_compat_raw_tp\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n-\t{ \"map_compat_raw_tp_w\", \"tracing progs cannot use bpf_{list_head,rb_root} yet\" },\n+\t{ \"map_compat_raw_tp_w\", \"calling kernel function bpf_list_push_front is not allowed\" },\n \t{ \"obj_type_id_oor\", \"local type ID argument must be in range [0, U32_MAX]\" },\n \t{ \"obj_new_no_composite\", \"bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct\" },\n \t{ \"obj_new_no_struct\", \"bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct\" },\ndiff --git a/tools/testing/selftests/bpf/prog_tests/map_btf.c b/tools/testing/selftests/bpf/prog_tests/map_btf.c\nindex 2c4ef6037573b6..1313f680fcdae1 100644\n--- a/tools/testing/selftests/bpf/prog_tests/map_btf.c\n+++ b/tools/testing/selftests/bpf/prog_tests/map_btf.c\n@@ -7,6 +7,7 @@\n \n static void do_test_normal_map_btf(void)\n {\n+\tLIBBPF_OPTS(bpf_test_run_opts, opts);\n \tstruct normal_map_btf *skel;\n \tint i, err, new_fd = -1;\n \tint map_fd_arr[64];\n@@ -15,12 +16,10 @@ static void do_test_normal_map_btf(void)\n \tif (!ASSERT_OK_PTR(skel, \"open_load\"))\n \t\treturn;\n \n-\terr = normal_map_btf__attach(skel);\n-\tif (!ASSERT_OK(err, \"attach\"))\n-\t\tgoto out;\n-\n \tskel-\u003ebss-\u003epid = getpid();\n-\tusleep(1);\n+\terr = bpf_prog_test_run_opts(bpf_program__fd(skel-\u003eprogs.add_to_list_in_array), \u0026opts);\n+\tif (!ASSERT_OK(err, \"test_run\"))\n+\t\tgoto out;\n \tASSERT_TRUE(skel-\u003ebss-\u003edone, \"done\");\n \n \t/* Use percpu_array to slow bpf_map_free_deferred() down.\n@@ -55,6 +54,7 @@ static void do_test_normal_map_btf(void)\n \n static void do_test_map_in_map_btf(void)\n {\n+\tLIBBPF_OPTS(bpf_test_run_opts, opts);\n \tint err, zero = 0, new_fd = -1;\n \tstruct map_in_map_btf *skel;\n \n@@ -62,12 +62,11 @@ static void do_test_map_in_map_btf(void)\n \tif (!ASSERT_OK_PTR(skel, \"open_load\"))\n \t\treturn;\n \n-\terr = map_in_map_btf__attach(skel);\n-\tif (!ASSERT_OK(err, \"attach\"))\n-\t\tgoto out;\n-\n \tskel-\u003ebss-\u003epid = getpid();\n-\tusleep(1);\n+\terr = bpf_prog_test_run_opts(bpf_program__fd(skel-\u003eprogs.add_to_list_in_inner_array),\n+\t\t\t\t \u0026opts);\n+\tif (!ASSERT_OK(err, \"test_run\"))\n+\t\tgoto out;\n \tASSERT_TRUE(skel-\u003ebss-\u003edone, \"done\");\n \n \t/* Close inner_array fd later */\ndiff --git a/tools/testing/selftests/bpf/progs/map_in_map_btf.c b/tools/testing/selftests/bpf/progs/map_in_map_btf.c\nindex 7a1336d7b16a63..eb4d009b8a62bc 100644\n--- a/tools/testing/selftests/bpf/progs/map_in_map_btf.c\n+++ b/tools/testing/selftests/bpf/progs/map_in_map_btf.c\n@@ -41,7 +41,7 @@ char _license[] SEC(\"license\") = \"GPL\";\n int pid = 0;\n bool done = false;\n \n-SEC(\"fentry/\" SYS_PREFIX \"sys_nanosleep\")\n+SEC(\"syscall\")\n int add_to_list_in_inner_array(void *ctx)\n {\n \tstruct map_value *value;\ndiff --git a/tools/testing/selftests/bpf/progs/normal_map_btf.c b/tools/testing/selftests/bpf/progs/normal_map_btf.c\nindex a45c9299552c99..90ac1ec365b96c 100644\n--- a/tools/testing/selftests/bpf/progs/normal_map_btf.c\n+++ b/tools/testing/selftests/bpf/progs/normal_map_btf.c\n@@ -29,7 +29,7 @@ char _license[] SEC(\"license\") = \"GPL\";\n int pid = 0;\n bool done = false;\n \n-SEC(\"fentry/\" SYS_PREFIX \"sys_nanosleep\")\n+SEC(\"syscall\")\n int add_to_list_in_array(void *ctx)\n {\n \tstruct map_value *value;\ndiff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr.c b/tools/testing/selftests/bpf/progs/refcounted_kptr.c\nindex 61906f48025cc7..9a783693ce087b 100644\n--- a/tools/testing/selftests/bpf/progs/refcounted_kptr.c\n+++ b/tools/testing/selftests/bpf/progs/refcounted_kptr.c\n@@ -921,11 +921,10 @@ long rbtree_wrong_owner_remove_fail_a2(void *ctx)\n \treturn 0;\n }\n \n-SEC(\"?fentry.s/\" SYS_PREFIX \"sys_getpgid\")\n+SEC(\"?lsm.s/bpf\")\n __success\n int BPF_PROG(rbtree_sleepable_rcu,\n-\t struct file *file, struct kobject *kobj,\n-\t struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)\n+\t int cmd, union bpf_attr *attr, unsigned int size, bool kernel)\n {\n \tstruct bpf_rb_node *rb;\n \tstruct node_data *n, *m = NULL;\n@@ -955,11 +954,10 @@ int BPF_PROG(rbtree_sleepable_rcu,\n \treturn 0;\n }\n \n-SEC(\"?fentry.s/\" SYS_PREFIX \"sys_getpgid\")\n+SEC(\"?lsm.s/bpf\")\n __success\n int BPF_PROG(rbtree_sleepable_rcu_no_explicit_rcu_lock,\n-\t struct file *file, struct kobject *kobj,\n-\t struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)\n+\t int cmd, union bpf_attr *attr, unsigned int size, bool kernel)\n {\n \tstruct bpf_rb_node *rb;\n \tstruct node_data *n, *m = NULL;\ndiff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c\nindex 024ef2aae20082..c47fc9d8e27fb2 100644\n--- a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c\n+++ b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c\n@@ -127,11 +127,10 @@ long refcount_acquire_list_node_offset(void *ctx)\n \treturn 0;\n }\n \n-SEC(\"?fentry.s/\" SYS_PREFIX \"sys_getpgid\")\n+SEC(\"?lsm.s/bpf\")\n __failure __msg(\"function calls are not allowed while holding a lock\")\n int BPF_PROG(rbtree_fail_sleepable_lock_across_rcu,\n-\t struct file *file, struct kobject *kobj,\n-\t struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)\n+\t int cmd, union bpf_attr *attr, unsigned int size, bool kernel)\n {\n \tstruct node_acquire *n;\n \ndiff --git a/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c b/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c\nindex 889c9b78b912e4..a87792353dfd4e 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c\n@@ -87,6 +87,7 @@ __naked void in_bpf_prog_type_kprobe_3(void)\n \tcall %[bpf_map_lookup_elem];\t\t\t\\\n \tif r0 == 0 goto l0_%=;\t\t\t\t\\\n \tr1 = r0;\t\t\t\t\t\\\n+\tr1 += 4;\t\t\t\t\t\\\n \tcall %[bpf_spin_lock];\t\t\t\t\\\n l0_%=:\texit;\t\t\t\t\t\t\\\n \"\t:\n@@ -110,6 +111,7 @@ __naked void in_bpf_prog_type_tracepoint_3(void)\n \tcall %[bpf_map_lookup_elem];\t\t\t\\\n \tif r0 == 0 goto l0_%=;\t\t\t\t\\\n \tr1 = r0;\t\t\t\t\t\\\n+\tr1 += 4;\t\t\t\t\t\\\n \tcall %[bpf_spin_lock];\t\t\t\t\\\n l0_%=:\texit;\t\t\t\t\t\t\\\n \"\t:\n@@ -133,6 +135,7 @@ __naked void bpf_prog_type_perf_event_3(void)\n \tcall %[bpf_map_lookup_elem];\t\t\t\\\n \tif r0 == 0 goto l0_%=;\t\t\t\t\\\n \tr1 = r0;\t\t\t\t\t\\\n+\tr1 += 4;\t\t\t\t\t\\\n \tcall %[bpf_spin_lock];\t\t\t\t\\\n l0_%=:\texit;\t\t\t\t\t\t\\\n \"\t:\n@@ -156,6 +159,7 @@ __naked void bpf_prog_type_raw_tracepoint_3(void)\n \tcall %[bpf_map_lookup_elem];\t\t\t\\\n \tif r0 == 0 goto l0_%=;\t\t\t\t\\\n \tr1 = r0;\t\t\t\t\t\\\n+\tr1 += 4;\t\t\t\t\t\\\n \tcall %[bpf_spin_lock];\t\t\t\t\\\n l0_%=:\texit;\t\t\t\t\t\t\\\n \"\t:\n"
} |
| 2/1 | 2026/07/19 12:09 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"BPF_EVENTS"
],
"FocusSymbols": [
"process_spin_lock",
"check_kfunc_args",
"check_map_prog_compatibility",
"check_kfunc_call"
],
"Reasoning": "The patch modifies the BPF verifier to change how tracing programs are restricted from using `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root`. It moves the restriction from map compatibility check to actual usage check, which is a functional change in the verifier logic that should be fuzzed.",
"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 ae2c54095e6e30511ddaf02671f604a154585afe
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Jul 19 12:09:46 2026 +0000
syz-cluster: applied patch under review
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a78cdabf85607f..3e42705dd66805 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -207,7 +207,7 @@ static int release_reference_nomark(struct bpf_verifier_state *state, int id);
static int release_reference(struct bpf_verifier_env *env, int id);
static void invalidate_non_owning_refs(struct bpf_verifier_env *env);
static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env);
-static bool is_tracing_prog_type(enum bpf_prog_type type);
+static bool is_tracing_prog_type(struct bpf_prog *prog);
static int ref_set_non_owning(struct bpf_verifier_env *env,
struct bpf_reg_state *reg);
static bool is_trusted_reg(struct bpf_verifier_env *env, const struct bpf_reg_state *reg);
@@ -7081,6 +7081,12 @@ static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state
val, lock_str, spin_lock_off);
return -EINVAL;
}
+
+ if (is_tracing_prog_type(env->prog) && !is_res_lock) {
+ verbose(env, "tracing progs cannot use bpf_spin_lock yet\n");
+ return -EINVAL;
+ }
+
if (is_lock) {
void *ptr;
int type;
@@ -12309,6 +12315,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
verbose(env, "allocated object must be referenced\n");
return -EINVAL;
}
+ if (is_tracing_prog_type(env->prog)) {
+ verbose(env, "tracing progs cannot use bpf_{list_head,rb_root} yet\n");
+ return -EINVAL;
+ }
ret = process_kf_arg_ptr_to_list_head(env, reg, argno, meta);
if (ret < 0)
return ret;
@@ -12325,6 +12335,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
verbose(env, "allocated object must be referenced\n");
return -EINVAL;
}
+ if (is_tracing_prog_type(env->prog)) {
+ verbose(env, "tracing progs cannot use bpf_{list_head,rb_root} yet\n");
+ return -EINVAL;
+ }
ret = process_kf_arg_ptr_to_rbtree_root(env, reg, argno, meta);
if (ret < 0)
return ret;
@@ -12958,7 +12972,6 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
int *insn_idx_p)
{
bool sleepable, rcu_lock, rcu_unlock, preempt_disable, preempt_enable;
- enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
struct bpf_reg_state *regs = cur_regs(env);
const char *func_name, *ptr_type_name;
const struct btf_type *t, *ptr_type;
@@ -13036,10 +13049,8 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
return err;
if ((is_bpf_obj_drop_kfunc(meta.func_id) ||
- is_bpf_percpu_obj_drop_kfunc(meta.func_id)) && (is_tracing_prog_type(prog_type) ||
- /* is_tracing_prog_type() for now doesn't cover non-iterator tracing progs. */
- (prog_type == BPF_PROG_TYPE_TRACING && env->prog->expected_attach_type != BPF_TRACE_ITER
- && !env->prog->sleepable))) {
+ is_bpf_percpu_obj_drop_kfunc(meta.func_id)) && (is_tracing_prog_type(env->prog)
+ && !env->prog->sleepable)) {
struct btf_struct_meta *struct_meta;
struct_meta = btf_find_struct_meta(meta.arg_btf, meta.arg_btf_id);
@@ -17761,9 +17772,11 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,
return __add_used_btf(env, btf);
}
-static bool is_tracing_prog_type(enum bpf_prog_type type)
+static bool is_tracing_prog_type(struct bpf_prog *prog)
{
- switch (type) {
+ switch (resolve_prog_type(prog)) {
+ case BPF_PROG_TYPE_TRACING:
+ return prog->expected_attach_type != BPF_TRACE_ITER;
case BPF_PROG_TYPE_KPROBE:
case BPF_PROG_TYPE_TRACEPOINT:
case BPF_PROG_TYPE_PERF_EVENT:
@@ -17794,26 +17807,19 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
return -EACCES;
}
- if (btf_record_has_field(map->record, BPF_LIST_HEAD) ||
- btf_record_has_field(map->record, BPF_RB_ROOT)) {
- if (is_tracing_prog_type(prog_type)) {
- verbose(env, "tracing progs cannot use bpf_{list_head,rb_root} yet\n");
- return -EINVAL;
- }
- }
-
if (btf_record_has_field(map->record, BPF_SPIN_LOCK | BPF_RES_SPIN_LOCK)) {
if (prog_type == BPF_PROG_TYPE_SOCKET_FILTER) {
verbose(env, "socket filter progs cannot use bpf_spin_lock yet\n");
return -EINVAL;
}
-
- if (is_tracing_prog_type(prog_type)) {
- verbose(env, "tracing progs cannot use bpf_spin_lock yet\n");
- return -EINVAL;
- }
}
+ /*
+ * Restrictions on using BPF list,rbtree,spin_lock is checked later upon
+ * use, since rejecting accesing map containing them in programs is too
+ * conservative.
+ */
+
if ((bpf_prog_is_offloaded(prog->aux) || bpf_map_is_offloaded(map)) &&
!bpf_offload_prog_map_match(prog, map)) {
verbose(env, "offload device mismatch between prog and map\n");
diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c
index c3d133c6a00d40..702268422673a1 100644
--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
@@ -59,12 +59,12 @@ static struct {
TEST(inner_map, pop_front)
TEST(inner_map, pop_back)
#undef TEST
- { "map_compat_kprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
- { "map_compat_kretprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
+ { "map_compat_kprobe", "calling kernel function bpf_list_push_front is not allowed" },
+ { "map_compat_kretprobe", "calling kernel function bpf_list_push_front is not allowed" },
{ "map_compat_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
{ "map_compat_perf", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
{ "map_compat_raw_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
- { "map_compat_raw_tp_w", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
+ { "map_compat_raw_tp_w", "calling kernel function bpf_list_push_front is not allowed" },
{ "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" },
{ "obj_new_no_composite", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
{ "obj_new_no_struct", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
diff --git a/tools/testing/selftests/bpf/prog_tests/map_btf.c b/tools/testing/selftests/bpf/prog_tests/map_btf.c
index 2c4ef6037573b6..1313f680fcdae1 100644
--- a/tools/testing/selftests/bpf/prog_tests/map_btf.c
+++ b/tools/testing/selftests/bpf/prog_tests/map_btf.c
@@ -7,6 +7,7 @@
static void do_test_normal_map_btf(void)
{
+ LIBBPF_OPTS(bpf_test_run_opts, opts);
struct normal_map_btf *skel;
int i, err, new_fd = -1;
int map_fd_arr[64];
@@ -15,12 +16,10 @@ static void do_test_normal_map_btf(void)
if (!ASSERT_OK_PTR(skel, "open_load"))
return;
- err = normal_map_btf__attach(skel);
- if (!ASSERT_OK(err, "attach"))
- goto out;
-
skel->bss->pid = getpid();
- usleep(1);
+ err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.add_to_list_in_array), &opts);
+ if (!ASSERT_OK(err, "test_run"))
+ goto out;
ASSERT_TRUE(skel->bss->done, "done");
/* Use percpu_array to slow bpf_map_free_deferred() down.
@@ -55,6 +54,7 @@ static void do_test_normal_map_btf(void)
static void do_test_map_in_map_btf(void)
{
+ LIBBPF_OPTS(bpf_test_run_opts, opts);
int err, zero = 0, new_fd = -1;
struct map_in_map_btf *skel;
@@ -62,12 +62,11 @@ static void do_test_map_in_map_btf(void)
if (!ASSERT_OK_PTR(skel, "open_load"))
return;
- err = map_in_map_btf__attach(skel);
- if (!ASSERT_OK(err, "attach"))
- goto out;
-
skel->bss->pid = getpid();
- usleep(1);
+ err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.add_to_list_in_inner_array),
+ &opts);
+ if (!ASSERT_OK(err, "test_run"))
+ goto out;
ASSERT_TRUE(skel->bss->done, "done");
/* Close inner_array fd later */
diff --git a/tools/testing/selftests/bpf/progs/map_in_map_btf.c b/tools/testing/selftests/bpf/progs/map_in_map_btf.c
index 7a1336d7b16a63..eb4d009b8a62bc 100644
--- a/tools/testing/selftests/bpf/progs/map_in_map_btf.c
+++ b/tools/testing/selftests/bpf/progs/map_in_map_btf.c
@@ -41,7 +41,7 @@ char _license[] SEC("license") = "GPL";
int pid = 0;
bool done = false;
-SEC("fentry/" SYS_PREFIX "sys_nanosleep")
+SEC("syscall")
int add_to_list_in_inner_array(void *ctx)
{
struct map_value *value;
diff --git a/tools/testing/selftests/bpf/progs/normal_map_btf.c b/tools/testing/selftests/bpf/progs/normal_map_btf.c
index a45c9299552c99..90ac1ec365b96c 100644
--- a/tools/testing/selftests/bpf/progs/normal_map_btf.c
+++ b/tools/testing/selftests/bpf/progs/normal_map_btf.c
@@ -29,7 +29,7 @@ char _license[] SEC("license") = "GPL";
int pid = 0;
bool done = false;
-SEC("fentry/" SYS_PREFIX "sys_nanosleep")
+SEC("syscall")
int add_to_list_in_array(void *ctx)
{
struct map_value *value;
diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr.c b/tools/testing/selftests/bpf/progs/refcounted_kptr.c
index 61906f48025cc7..9a783693ce087b 100644
--- a/tools/testing/selftests/bpf/progs/refcounted_kptr.c
+++ b/tools/testing/selftests/bpf/progs/refcounted_kptr.c
@@ -921,11 +921,10 @@ long rbtree_wrong_owner_remove_fail_a2(void *ctx)
return 0;
}
-SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
+SEC("?lsm.s/bpf")
__success
int BPF_PROG(rbtree_sleepable_rcu,
- struct file *file, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)
+ int cmd, union bpf_attr *attr, unsigned int size, bool kernel)
{
struct bpf_rb_node *rb;
struct node_data *n, *m = NULL;
@@ -955,11 +954,10 @@ int BPF_PROG(rbtree_sleepable_rcu,
return 0;
}
-SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
+SEC("?lsm.s/bpf")
__success
int BPF_PROG(rbtree_sleepable_rcu_no_explicit_rcu_lock,
- struct file *file, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)
+ int cmd, union bpf_attr *attr, unsigned int size, bool kernel)
{
struct bpf_rb_node *rb;
struct node_data *n, *m = NULL;
diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c
index 024ef2aae20082..c47fc9d8e27fb2 100644
--- a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c
+++ b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c
@@ -127,11 +127,10 @@ long refcount_acquire_list_node_offset(void *ctx)
return 0;
}
-SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
+SEC("?lsm.s/bpf")
__failure __msg("function calls are not allowed while holding a lock")
int BPF_PROG(rbtree_fail_sleepable_lock_across_rcu,
- struct file *file, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)
+ int cmd, union bpf_attr *attr, unsigned int size, bool kernel)
{
struct node_acquire *n;
diff --git a/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c b/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c
index 889c9b78b912e4..a87792353dfd4e 100644
--- a/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c
+++ b/tools/testing/selftests/bpf/progs/verifier_helper_restricted.c
@@ -87,6 +87,7 @@ __naked void in_bpf_prog_type_kprobe_3(void)
call %[bpf_map_lookup_elem]; \
if r0 == 0 goto l0_%=; \
r1 = r0; \
+ r1 += 4; \
call %[bpf_spin_lock]; \
l0_%=: exit; \
" :
@@ -110,6 +111,7 @@ __naked void in_bpf_prog_type_tracepoint_3(void)
call %[bpf_map_lookup_elem]; \
if r0 == 0 goto l0_%=; \
r1 = r0; \
+ r1 += 4; \
call %[bpf_spin_lock]; \
l0_%=: exit; \
" :
@@ -133,6 +135,7 @@ __naked void bpf_prog_type_perf_event_3(void)
call %[bpf_map_lookup_elem]; \
if r0 == 0 goto l0_%=; \
r1 = r0; \
+ r1 += 4; \
call %[bpf_spin_lock]; \
l0_%=: exit; \
" :
@@ -156,6 +159,7 @@ __naked void bpf_prog_type_raw_tracepoint_3(void)
call %[bpf_map_lookup_elem]; \
if r0 == 0 goto l0_%=; \
r1 = r0; \
+ r1 += 4; \
call %[bpf_spin_lock]; \
l0_%=: exit; \
" :
|
| 3/2 | 2026/07/19 12:09 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6871 output: 35 thoughts: 250 Thoughts: **Analyzing the BPF Verifier Patch** Okay, so I'm looking at this patch and it's making some pretty significant changes to the BPF verifier, specifically in `kernel/bpf/verifier.c`. It looks like the focus is on how we handle tracing programs, and how certain data structures interact with those programs. The main point is that `is_tracing_prog_type` has been refactored. Before, it was a straightforward check based on the program type directly. Now, it takes a `struct bpf_prog *prog` as input. This implies a shift to a more granular approach, using `resolve_prog_type(prog)` to determine the actual program type and returning `prog->expected_attach_type != BPF_TRACE_ITER`. This is interesting; it looks like we're considering the *expected* attach type, making this more nuanced. It seems the intention here is to refine the criteria for whether a program is treated as a tracing program. The other major change is about where the checks for things like `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root` happen. Previously, this compatibility check was done in `check_map_prog_compatibility`, but now, it appears those checks are *moved* to `process_spin_lock` and `check_kfunc_args`. That means we are no longer checking them when a map is accessed, but rather when they are *used* in a program. This changes the timing of the verifier checks. I need to dive into the verifier.c code to confirm the context and fully understand the implications. |
| 4/2 | 2026/07/19 12:09 | tool | grepper |
0mArgs:{
"Expression": "is_tracing_prog_type",
"PathPrefix": "kernel/bpf/verifier.c"
}Results: {
"Output": "kernel/bpf/verifier.c=209=static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env);\nkernel/bpf/verifier.c:210:static bool is_tracing_prog_type(struct bpf_prog *prog);\nkernel/bpf/verifier.c-211-static int ref_set_non_owning(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c=7040=static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state *reg, argno_t argno, int flags)\n--\nkernel/bpf/verifier.c-7084-\nkernel/bpf/verifier.c:7085:\tif (is_tracing_prog_type(env-\u003eprog) \u0026\u0026 !is_res_lock) {\nkernel/bpf/verifier.c-7086-\t\tverbose(env, \"tracing progs cannot use bpf_spin_lock yet\\n\");\n--\nkernel/bpf/verifier.c=11992=static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,\n--\nkernel/bpf/verifier.c-12317-\t\t\t}\nkernel/bpf/verifier.c:12318:\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\nkernel/bpf/verifier.c-12319-\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n--\nkernel/bpf/verifier.c-12337-\t\t\t}\nkernel/bpf/verifier.c:12338:\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\nkernel/bpf/verifier.c-12339-\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n--\nkernel/bpf/verifier.c=12971=static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,\n--\nkernel/bpf/verifier.c-13051-\tif ((is_bpf_obj_drop_kfunc(meta.func_id) ||\nkernel/bpf/verifier.c:13052:\t is_bpf_percpu_obj_drop_kfunc(meta.func_id)) \u0026\u0026 (is_tracing_prog_type(env-\u003eprog)\nkernel/bpf/verifier.c-13053-\t \u0026\u0026 !env-\u003eprog-\u003esleepable)) {\n--\nkernel/bpf/verifier.c=17742=static int check_pseudo_btf_id(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c-17774-\nkernel/bpf/verifier.c:17775:static bool is_tracing_prog_type(struct bpf_prog *prog)\nkernel/bpf/verifier.c-17776-{\n"
} |
| 5/2 | 2026/07/19 12:09 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8285 output: 31 thoughts: 310 Thoughts: **My Assessment of the BPF Verifier Patch** Okay, so this patch is tweaking how the BPF verifier interacts with `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root` when tracing programs are involved. Essentially, we're now *allowing* maps containing these types to be used within tracing programs, but we're still *rejecting* the *actual* usage of those fields within the trace programs themselves. Makes sense – flexibility with the map layout, but enforcing safety on the program's operations. This is definitely a functional change in the verifier's behavior. The implication of this change is it should be fuzzed to see if any new attack surfaces have been exposed. Now, let's nail down the critical bits. The key symbols affected look like: `process_spin_lock`, `check_kfunc_args`, `check_kfunc_call`, `is_tracing_prog_type`, and `check_map_prog_compatibility`. `is_tracing_prog_type` is likely a minor helper function. My attention is drawn to `process_spin_lock`, `check_kfunc_args`, `check_kfunc_call`, and `check_map_prog_compatibility` as the more interesting pieces. Now, we need to consider the execution frequency. These functions reside within `kernel/bpf/verifier.c`, which, as I recall, is where the BPF verifier itself lives. The verifier runs during program *load* time, not during program *execution*. So, these aren't hot-path functions, not executed per packet or per event. That's good to know for prioritizing fuzzing efforts. The fact that the verifier runs at load time means it likely has some configuration requirements. The BPF verifier, I recall, requires `CONFIG_BPF_SYSCALL`. |
| 6/2 | 2026/07/19 12:10 | tool | grepper |
0mError:no matches Args: {
"Expression": "config BPF_SYSCALL",
"PathPrefix": "init/Kconfig"
}Results: {
"error": "no matches"
} |
| 7/2 | 2026/07/19 12:10 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9048 output: 27 thoughts: 16 Thoughts: Okay, here's my attempt at summarizing that thought process, tailored for an expert audience: **Tracing Down `BPF_SYSCALL`** Alright, so I need to understand how `BPF_SYSCALL` is defined. This likely means I'm looking at how syscalls are being hooked or potentially filtered with eBPF. I'll need to figure out where that macro is declared, probably in a kernel header file. I'm guessing it's part of the core BPF infrastructure, maybe related to the tracing or kprobes modules. I'll probably start with the standard include directories, something like `/usr/src/linux/include/`, or wherever the kernel headers reside on this system. From there, I'll need to use some clever searching techniques. `grep` is probably the immediate tool, but I might use a more precise command like `find` and then `grep` to narrow down the search if I know some related keywords, like "bpf", "syscall", or "hook". I'm anticipating it'll be a fairly involved macro, probably something that expands to a specific eBPF instruction or a series of instructions related to a syscall entry point. I'll also want to consider what kernel versions might be relevant, and look into the specific header location for each version if necessary, as kernel API changes can affect this sort of thing. |
| 8/2 | 2026/07/19 12:10 | tool | grepper |
0mArgs:{
"Expression": "config BPF_SYSCALL",
"PathPrefix": ""
}Results: {
"Output": "kernel/bpf/Kconfig=25=menu \"BPF subsystem\"\nkernel/bpf/Kconfig-26-\nkernel/bpf/Kconfig:27:config BPF_SYSCALL\nkernel/bpf/Kconfig-28-\tbool \"Enable bpf() system call\"\n"
} |
| 9/2 | 2026/07/19 12:10 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9466 output: 25 thoughts: 37 Thoughts: Here's a summary of my current understanding, focusing on what I need to consider when working with BPF: **My BPF Configuration Considerations** Okay, so I'm diving into BPF again, and the main thing to ensure is that I have `BPF_SYSCALL` enabled in the kernel config. That's the core. But, knowing my luck and the flexibility of BPF, I also need to be mindful of a couple of other key configurations. If I'm working on tracing programs, which I often am for performance analysis and security, then I'll definitely need to double-check that either `CONFIG_BPF_EVENTS` or `CONFIG_TRACING` are enabled as well. They're essential for getting the data I need from those tracing probes. So, core BPF, plus tracing, and that's the starting point. I need to keep that in mind as I start to write a BPF program or load any eBPF programs. |
| 10/2 | 2026/07/19 12:10 | tool | grepper |
0mArgs:{
"Expression": "config BPF_EVENTS",
"PathPrefix": ""
}Results: {
"Output": "kernel/trace/Kconfig=839=config EPROBE_EVENTS\n--\nkernel/trace/Kconfig-852-\nkernel/trace/Kconfig:853:config BPF_EVENTS\nkernel/trace/Kconfig-854-\tdepends on BPF_SYSCALL\n"
} |
| 11/2 | 2026/07/19 12:10 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9818 output: 33 thoughts: 185 Thoughts: **Analyzing the BPF Verifier Patch** Okay, first things first, let's see if this patch touches any other configuration aspects beyond the obvious. It looks like the core modification is in `kernel/bpf/verifier.c`. Definitely need `CONFIG_BPF_SYSCALL` for this to even run, and `CONFIG_BPF_EVENTS` is probably relevant for tracing capabilities within the patch. Now, let's zero in on the key symbols this patch seems to be touching. I'm seeing: `process_spin_lock`, `check_kfunc_args`, `check_map_prog_compatibility`, and `is_tracing_prog_type`. Hold on a second... `is_tracing_prog_type` is static, which is usually not a problem, but with Syzkaller, inlining could mess with this. It's fuzzable now. Let's just focus on the non-static ones for now. So, `process_spin_lock`, `check_kfunc_args`, and `check_map_prog_compatibility` are the main candidates. I should probably double-check `process_spin_lock` in `kernel/bpf/verifier.c` to be sure. |
| 12/2 | 2026/07/19 12:10 | tool | grepper |
0mArgs:{
"Expression": "process_spin_lock",
"PathPrefix": "kernel/bpf/verifier.c"
}Results: {
"Output": "kernel/bpf/verifier.c=7012=enum {\n--\nkernel/bpf/verifier.c-7039- */\nkernel/bpf/verifier.c:7040:static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state *reg, argno_t argno, int flags)\nkernel/bpf/verifier.c-7041-{\n--\nkernel/bpf/verifier.c=8287=static int check_func_arg(struct bpf_verifier_env *env, u32 arg,\n--\nkernel/bpf/verifier.c-8453-\t\tif (meta-\u003efunc_id == BPF_FUNC_spin_lock) {\nkernel/bpf/verifier.c:8454:\t\t\terr = process_spin_lock(env, reg, argno, PROCESS_SPIN_LOCK);\nkernel/bpf/verifier.c-8455-\t\t\tif (err)\n--\nkernel/bpf/verifier.c-8457-\t\t} else if (meta-\u003efunc_id == BPF_FUNC_spin_unlock) {\nkernel/bpf/verifier.c:8458:\t\t\terr = process_spin_lock(env, reg, argno, 0);\nkernel/bpf/verifier.c-8459-\t\t\tif (err)\n--\nkernel/bpf/verifier.c=11992=static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,\n--\nkernel/bpf/verifier.c-12564-\t\t\t\tflags |= PROCESS_LOCK_IRQ;\nkernel/bpf/verifier.c:12565:\t\t\tret = process_spin_lock(env, reg, argno, flags);\nkernel/bpf/verifier.c-12566-\t\t\tif (ret \u003c 0)\n"
} |
| 13/2 | 2026/07/19 12:10 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10776 output: 35 thoughts: 55 Thoughts: Okay, here's my take on those code symbols, thinking as a seasoned expert: **Reflecting on Code Symbol Focus** Alright, after reviewing the candidate symbols, I think we have a solid starting point. Yes, focusing on `process_spin_lock` is definitely a good choice. It likely represents a core synchronization mechanism, making it a pivotal area to understand for concurrency-related issues. The function `check_map_prog_compatibility` is also promising. That suggests this code is dealing with the interaction between data structures and program types, which is a common area for subtle bugs and performance bottlenecks, especially in more complex systems. And then we have `check_kfunc_args`. Perfect. This hints at careful argument validation for kernel functions. Validation errors at this level can lead to crashes, security vulnerabilities, or hard-to-debug misbehavior, so focusing on this symbol is also spot on. Now, let me just check `is_tracing_prog_type`. Let's see how that fits into the picture. Tracing can be another great focal point, and the interaction of tracing with concurrency, map types, and kfuncs is something I would immediately be curious about. |
| 14/2 | 2026/07/19 12:10 | tool | grepper |
0mArgs:{
"Expression": "is_tracing_prog_type",
"PathPrefix": "kernel/bpf/verifier.c"
}Results: {
"Output": "kernel/bpf/verifier.c=209=static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env);\nkernel/bpf/verifier.c:210:static bool is_tracing_prog_type(struct bpf_prog *prog);\nkernel/bpf/verifier.c-211-static int ref_set_non_owning(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c=7040=static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state *reg, argno_t argno, int flags)\n--\nkernel/bpf/verifier.c-7084-\nkernel/bpf/verifier.c:7085:\tif (is_tracing_prog_type(env-\u003eprog) \u0026\u0026 !is_res_lock) {\nkernel/bpf/verifier.c-7086-\t\tverbose(env, \"tracing progs cannot use bpf_spin_lock yet\\n\");\n--\nkernel/bpf/verifier.c=11992=static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,\n--\nkernel/bpf/verifier.c-12317-\t\t\t}\nkernel/bpf/verifier.c:12318:\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\nkernel/bpf/verifier.c-12319-\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n--\nkernel/bpf/verifier.c-12337-\t\t\t}\nkernel/bpf/verifier.c:12338:\t\t\tif (is_tracing_prog_type(env-\u003eprog)) {\nkernel/bpf/verifier.c-12339-\t\t\t\tverbose(env, \"tracing progs cannot use bpf_{list_head,rb_root} yet\\n\");\n--\nkernel/bpf/verifier.c=12971=static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,\n--\nkernel/bpf/verifier.c-13051-\tif ((is_bpf_obj_drop_kfunc(meta.func_id) ||\nkernel/bpf/verifier.c:13052:\t is_bpf_percpu_obj_drop_kfunc(meta.func_id)) \u0026\u0026 (is_tracing_prog_type(env-\u003eprog)\nkernel/bpf/verifier.c-13053-\t \u0026\u0026 !env-\u003eprog-\u003esleepable)) {\n--\nkernel/bpf/verifier.c=17742=static int check_pseudo_btf_id(struct bpf_verifier_env *env,\n--\nkernel/bpf/verifier.c-17774-\nkernel/bpf/verifier.c:17775:static bool is_tracing_prog_type(struct bpf_prog *prog)\nkernel/bpf/verifier.c-17776-{\n"
} |
| 15/2 | 2026/07/19 12:10 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11890 output: 153 thoughts: 146 Thoughts: **My Assessment of the BPF Verifier Patch** Okay, so this patch is a functional tweak to the BPF verifier. It's really focusing on how tracing programs interact with some fundamental BPF data structures – namely, `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root`. The clever move here is shifting the compatibility checks. Instead of immediately blocking maps containing these types from *any* tracing program, the verifier will now wait until those fields are *actually used* within the program. This is much more nuanced. Essentially, the patch is saying, "it's okay to define a map *with* these fields, even for a tracing program, as long as the tracing program doesn't attempt to access the potentially problematic fields." This should open up more flexibility for developers. I'm thinking this deserves some serious fuzzing. So, I'm setting `WorthFuzzing=true`. For focused testing, I'll need to concentrate on these key symbols: `process_spin_lock`, `check_kfunc_args`, `check_map_prog_compatibility`, and `check_kfunc_call`. They are directly involved in the logic this patch alters. Finally, to make sure I'm exercising the code properly, I'll need to enable `BPF_SYSCALL` and `BPF_EVENTS` in the configuration. That will ensure the relevant functionality is available for testing. |
| 16/2 | 2026/07/19 12:10 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_SYSCALL",
"BPF_EVENTS"
],
"FocusSymbols": [
"process_spin_lock",
"check_kfunc_args",
"check_map_prog_compatibility",
"check_kfunc_call"
],
"Reasoning": "The patch modifies the BPF verifier to change how tracing programs are restricted from using `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root`. It moves the restriction from map compatibility check to actual usage check, which is a functional change in the verifier logic that should be fuzzed.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"BPF_EVENTS"
],
"FocusSymbols": [
"process_spin_lock",
"check_kfunc_args",
"check_map_prog_compatibility",
"check_kfunc_call"
],
"Reasoning": "The patch modifies the BPF verifier to change how tracing programs are restricted from using `bpf_spin_lock`, `bpf_list_head`, and `bpf_rb_root`. It moves the restriction from map compatibility check to actual usage check, which is a functional change in the verifier logic that should be fuzzed.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|