| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/29 05:36 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_mprog_attach",
"bpf_mprog_detach",
"bpf_mprog_query"
],
"Reasoning": "The patch fixes a race condition in BPF mprog link handling by adding RCU read lock and READ_ONCE when accessing link-\u003eprog. This is reachable via BPF syscalls (attach, detach, query) and modifies core BPF logic.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/29 05:36 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit b9f350a5f4c39c0755a519c5c3be53adfded3493\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Jul 29 05:36:30 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c\nindex 1394168062e85..af3e6c1c6a1f1 100644\n--- a/kernel/bpf/mprog.c\n+++ b/kernel/bpf/mprog.c\n@@ -10,6 +10,8 @@ static int bpf_mprog_link(struct bpf_tuple *tuple,\n {\n \tstruct bpf_link *link = ERR_PTR(-EINVAL);\n \tbool id = flags \u0026 BPF_F_ID;\n+\tbool type_mismatch = false;\n+\tstruct bpf_prog *prog;\n \n \tif (id)\n \t\tlink = bpf_link_by_id(id_or_fd);\n@@ -17,13 +19,20 @@ static int bpf_mprog_link(struct bpf_tuple *tuple,\n \t\tlink = bpf_link_get_from_fd(id_or_fd);\n \tif (IS_ERR(link))\n \t\treturn PTR_ERR(link);\n-\tif (type \u0026\u0026 link-\u003eprog-\u003etype != type) {\n+\n+\trcu_read_lock();\n+\tprog = READ_ONCE(link-\u003eprog);\n+\tif (!prog || (type \u0026\u0026 prog-\u003etype != type))\n+\t\ttype_mismatch = true;\n+\trcu_read_unlock();\n+\n+\tif (type_mismatch) {\n \t\tbpf_link_put(link);\n \t\treturn -EINVAL;\n \t}\n \n \ttuple-\u003elink = link;\n-\ttuple-\u003eprog = link-\u003eprog;\n+\ttuple-\u003eprog = prog;\n \treturn 0;\n }\n \n@@ -343,8 +352,8 @@ int bpf_mprog_detach(struct bpf_mprog_entry *entry,\n \tif (!bpf_mprog_total(entry))\n \t\treturn -ENOENT;\n \tret = bpf_mprog_tuple_relative(\u0026rtuple, id_or_fd, flags,\n-\t\t\t\t prog ? prog-\u003etype :\n-\t\t\t\t BPF_PROG_TYPE_UNSPEC);\n+\t\t\t\t /* Use UNSPEC as wildcard when prog is NULL */\n+\t\t\t\t prog ? prog-\u003etype : BPF_PROG_TYPE_UNSPEC);\n \tif (ret)\n \t\treturn ret;\n \tif (dtuple.prog) {\n"
} |
| 2/1 | 2026/07/29 05:36 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_mprog_attach",
"bpf_mprog_detach",
"bpf_mprog_query"
],
"Reasoning": "The patch fixes a race condition in BPF mprog link handling by adding RCU read lock and READ_ONCE when accessing link-\u003eprog. This is reachable via BPF syscalls (attach, detach, query) and modifies 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). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. 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. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 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. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. 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 b9f350a5f4c39c0755a519c5c3be53adfded3493
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Jul 29 05:36:30 2026 +0000
syz-cluster: applied patch under review
diff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c
index 1394168062e85..af3e6c1c6a1f1 100644
--- a/kernel/bpf/mprog.c
+++ b/kernel/bpf/mprog.c
@@ -10,6 +10,8 @@ static int bpf_mprog_link(struct bpf_tuple *tuple,
{
struct bpf_link *link = ERR_PTR(-EINVAL);
bool id = flags & BPF_F_ID;
+ bool type_mismatch = false;
+ struct bpf_prog *prog;
if (id)
link = bpf_link_by_id(id_or_fd);
@@ -17,13 +19,20 @@ static int bpf_mprog_link(struct bpf_tuple *tuple,
link = bpf_link_get_from_fd(id_or_fd);
if (IS_ERR(link))
return PTR_ERR(link);
- if (type && link->prog->type != type) {
+
+ rcu_read_lock();
+ prog = READ_ONCE(link->prog);
+ if (!prog || (type && prog->type != type))
+ type_mismatch = true;
+ rcu_read_unlock();
+
+ if (type_mismatch) {
bpf_link_put(link);
return -EINVAL;
}
tuple->link = link;
- tuple->prog = link->prog;
+ tuple->prog = prog;
return 0;
}
@@ -343,8 +352,8 @@ int bpf_mprog_detach(struct bpf_mprog_entry *entry,
if (!bpf_mprog_total(entry))
return -ENOENT;
ret = bpf_mprog_tuple_relative(&rtuple, id_or_fd, flags,
- prog ? prog->type :
- BPF_PROG_TYPE_UNSPEC);
+ /* Use UNSPEC as wildcard when prog is NULL */
+ prog ? prog->type : BPF_PROG_TYPE_UNSPEC);
if (ret)
return ret;
if (dtuple.prog) {
|
| 3/2 | 2026/07/29 05:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 2445 output: 36 thoughts: 246 Thoughts: **Analyzing the BPF Mprog Patch** Okay, so this patch looks like it's touching `kernel/bpf/mprog.c`. Right, diving in, it seems the core of the change is focused on `bpf_mprog_link`. Specifically, they've added an RCU read lock and are using `READ_ONCE(link->prog)` when reading `link->prog` within that function. Makes sense, that's the standard approach to ensuring safe reads of potentially concurrent data structures in the kernel, good catch. The aim is to make the program type check safer. I see that `bpf_mprog_detach` also gets a slight tweak. It's essentially the same logic for checking the program type as before, using `prog ? prog->type : BPF_PROG_TYPE_UNSPEC`, but the formatting's been cleaned up and there's a new comment. Probably for readability, fine. Now, let me confirm the call hierarchy here. Let's see... `bpf_mprog_link` is called from `bpf_mprog_tuple_relative`, which is then invoked from `bpf_mprog_detach`, `bpf_mprog_attach`, and others. Excellent, that's what I suspected, this is directly reachable and functional via the BPF syscalls, so this is definitely worth examining more closely. Just to be sure I'm not missing anything, a quick search for those two functions... `bpf_mprog_link` and `bpf_mprog_detach`... just to get a lay of the land and verify my assumptions. |
| 4/2 | 2026/07/29 05:36 | tool | grepper |
0mArgs:{
"Expression": "bpf_mprog_link",
"PathPrefix": "kernel/bpf/mprog.c"
}Results: {
"Output": "kernel/bpf/mprog.c-6-\nkernel/bpf/mprog.c:7:static int bpf_mprog_link(struct bpf_tuple *tuple,\nkernel/bpf/mprog.c-8-\t\t\t u32 id_or_fd, u32 flags,\n--\nkernel/bpf/mprog.c=62=static int bpf_mprog_tuple_relative(struct bpf_tuple *tuple,\n--\nkernel/bpf/mprog.c-70-\tif (link)\nkernel/bpf/mprog.c:71:\t\treturn bpf_mprog_link(tuple, id_or_fd, flags, type);\nkernel/bpf/mprog.c-72-\t/* If no relevant flag is set and no id_or_fd was passed, then\n"
} |
| 5/2 | 2026/07/29 05:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3290 output: 30 thoughts: 38 Thoughts: Okay, let's see. My first thought is to zero in on the necessary configuration options. I need to understand what's required for this particular aspect. Right, so looking at the code... `kernel/bpf/mprog.c` is the relevant file here. Crucially, it's only compiled if `CONFIG_BPF_SYSCALL` is enabled. That's the key dependency I need to remember. |
| 6/2 | 2026/07/29 05:36 | tool | grepper |
0mArgs:{
"Expression": "mprog.o",
"PathPrefix": "kernel/bpf/Makefile"
}Results: {
"Output": "kernel/bpf/Makefile=15=obj-${CONFIG_BPF_LSM}\t += bpf_inode_storage.o\nkernel/bpf/Makefile:16:obj-$(CONFIG_BPF_SYSCALL) += disasm.o mprog.o\nkernel/bpf/Makefile-17-obj-$(CONFIG_BPF_JIT) += trampoline.o\n"
} |
| 7/2 | 2026/07/29 05:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3554 output: 37 thoughts: 71 Thoughts: **BPF Program Management Module Deep Dive** Okay, so I'm diving into the BPF program management aspect, specifically looking at the `CONFIG_BPF_SYSCALL` configuration option, as that's the primary enabler here. I need to get a clear picture of how BPF programs are attached, detached, and queried, so I'm zeroing in on those crucial symbols: `bpf_mprog_detach`, `bpf_mprog_attach`, and `bpf_mprog_query`. My goal is to understand the control flow. I should probably start by examining `kernel/bpf/mprog.c` and figure out what functions are actually exposed and not declared as static within that file. This should give me a good baseline for how the program interaction works from a high-level. |
| 8/2 | 2026/07/29 05:36 | tool | grepper |
0mArgs:{
"Expression": "^int bpf_mprog_",
"PathPrefix": "kernel/bpf/mprog.c"
}Results: {
"Output": "kernel/bpf/mprog.c=218=static int bpf_mprog_pos_after(struct bpf_mprog_entry *entry,\n--\nkernel/bpf/mprog.c-233-\nkernel/bpf/mprog.c:234:int bpf_mprog_attach(struct bpf_mprog_entry *entry,\nkernel/bpf/mprog.c-235-\t\t struct bpf_mprog_entry **entry_new,\n--\nkernel/bpf/mprog.c=306=static int bpf_mprog_fetch(struct bpf_mprog_entry *entry,\n--\nkernel/bpf/mprog.c-336-\nkernel/bpf/mprog.c:337:int bpf_mprog_detach(struct bpf_mprog_entry *entry,\nkernel/bpf/mprog.c-338-\t\t struct bpf_mprog_entry **entry_new,\n--\nkernel/bpf/mprog.c-403-\nkernel/bpf/mprog.c:404:int bpf_mprog_query(const union bpf_attr *attr, union bpf_attr __user *uattr,\nkernel/bpf/mprog.c-405-\t\t struct bpf_mprog_entry *entry)\n"
} |
| 9/2 | 2026/07/29 05:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 4178 output: 120 thoughts: 210 Thoughts: **Analyzing the BPF Program Attachment/Detachment Patch** Okay, so I'm looking at this patch and immediately, my focus is on the core BPF multi-program interaction functions: `bpf_mprog_attach`, `bpf_mprog_detach`, and `bpf_mprog_query`. Those are the entry points. The patch seems to be touching `bpf_mprog_link` (static within this context) and `bpf_mprog_detach`. Hmm, I should keep an eye on those three primary symbols: `bpf_mprog_attach`, `bpf_mprog_detach`, and `bpf_mprog_query`. Wait a minute, `bpf_mprog_link`... that's *called* from `bpf_mprog_tuple_relative`, and *that* function is called by both `bpf_mprog_attach` and `bpf_mprog_detach`! That's important context. Alright, now let's quickly check whether `BPF_SYSCALL` is the right trigger... Yes, that checks out. No problem here. Fuzzing? Definitely worth it. Fixing that race condition where `link->prog` might be read as NULL or changed mid-operation, leading to a crash or type mismatch? Absolutely. We need to lock that down. Right, time to call set-results. |
| 10/2 | 2026/07/29 05:36 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_mprog_attach",
"bpf_mprog_detach",
"bpf_mprog_query"
],
"Reasoning": "The patch fixes a race condition in BPF mprog link handling by adding RCU read lock and READ_ONCE when accessing link-\u003eprog. This is reachable via BPF syscalls (attach, detach, query) and modifies core BPF logic.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_mprog_attach",
"bpf_mprog_detach",
"bpf_mprog_query"
],
"Reasoning": "The patch fixes a race condition in BPF mprog link handling by adding RCU read lock and READ_ONCE when accessing link-\u003eprog. This is reachable via BPF syscalls (attach, detach, query) and modifies core BPF logic.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|