| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/26 17:51 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_JIT",
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_jit_binary_pack_alloc",
"bpf_jit_binary_pack_finalize",
"bpf_jit_binary_pack_free",
"bpf_jit_binary_hdr",
"bpf_int_jit_compile",
"bpf_jit_free"
],
"Reasoning": "The patch fixes memory leaks and incorrect freeing of BPF JIT headers and data during JIT compilation failures or when freeing BPF programs. It modifies core BPF JIT memory management functions and architecture-specific JIT compilers. These changes are functional, reachable from user space via the bpf() syscall, and should be fuzzed to ensure no memory leaks or use-after-free issues occur during BPF program load/unload.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/26 17:51 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 0bab7a5396f10cb242b6fea4e99338c0c1373d46\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Jul 26 17:51:35 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c\nindex 639a2736f029ed..29c8933e2dd2ce 100644\n--- a/arch/arc/net/bpf_jit_core.c\n+++ b/arch/arc/net/bpf_jit_core.c\n@@ -1412,3 +1412,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \n \treturn prog;\n }\n+\n+void bpf_jit_free(struct bpf_prog *fp)\n+{\n+\tif (fp-\u003ejited) {\n+\t\tstruct arc_jit_data *jit_data = fp-\u003eaux-\u003ejit_data;\n+\t\tstruct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);\n+\n+\t\t/* Cleanup for earlier subprogs if jit_subprogs() aborts */\n+\t\tif (jit_data) {\n+\t\t\tkfree(jit_data-\u003ebpf2insn);\n+\t\t\tkfree(jit_data);\n+\t\t}\n+\n+\t\tbpf_jit_binary_free(hdr);\n+\t\tWARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));\n+\t}\n+\n+\tbpf_prog_unlock_free(fp);\n+}\ndiff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c\nindex 4cdc7dfb05ba9a..32780247305eb0 100644\n--- a/arch/arm64/net/bpf_jit_comp.c\n+++ b/arch/arm64/net/bpf_jit_comp.c\n@@ -2258,7 +2258,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\t\tgoto out_free_hdr;\n \t\t}\n \t\tif (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) {\n-\t\t\t/* ro_header and header has been freed */\n+\t\t\tbpf_jit_binary_pack_free(ro_header, NULL);\n \t\t\tro_header = NULL;\n \t\t\theader = NULL;\n \t\t\tgoto out_free_hdr;\n@@ -2308,9 +2308,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\tprog-\u003ejited_len = 0;\n \t}\n \tif (header) {\n-\t\tbpf_arch_text_copy(\u0026ro_header-\u003esize, \u0026header-\u003esize,\n-\t\t\t\t sizeof(header-\u003esize));\n \t\tbpf_jit_binary_pack_free(ro_header, header);\n+\t\tro_header = NULL;\n \t}\n \tgoto out_off;\n }\n@@ -3237,6 +3236,7 @@ void bpf_jit_free(struct bpf_prog *prog)\n \t\t */\n \t\tif (jit_data) {\n \t\t\tbpf_jit_binary_pack_finalize(jit_data-\u003ero_header, jit_data-\u003eheader);\n+\t\t\tkvfree(jit_data-\u003ectx.offset);\n \t\t\tkfree(jit_data);\n \t\t}\n \t\tprog-\u003ebpf_func = (void *)prog-\u003ebpf_func - cfi_get_offset();\ndiff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c\nindex 2738b4db116533..48ad418df1331a 100644\n--- a/arch/loongarch/net/bpf_jit.c\n+++ b/arch/loongarch/net/bpf_jit.c\n@@ -2298,7 +2298,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\t\tgoto out_free;\n \t\t}\n \t\tif (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) {\n-\t\t\t/* ro_header and header have been freed */\n+\t\t\tbpf_jit_binary_pack_free(ro_header, NULL);\n \t\t\tro_header = NULL;\n \t\t\theader = NULL;\n \t\t\tgoto out_free;\n@@ -2341,10 +2341,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\tprog-\u003ejited_len = 0;\n \t}\n \n-\tif (header) {\n-\t\tbpf_arch_text_copy(\u0026ro_header-\u003esize, \u0026header-\u003esize, sizeof(header-\u003esize));\n+\tif (header)\n \t\tbpf_jit_binary_pack_free(ro_header, header);\n-\t}\n \tgoto out_offset;\n }\n \ndiff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c\nindex 172770132440db..ef63c38bdf1510 100644\n--- a/arch/parisc/net/bpf_jit_core.c\n+++ b/arch/parisc/net/bpf_jit_core.c\n@@ -178,6 +178,25 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \tgoto out_offset;\n }\n \n+void bpf_jit_free(struct bpf_prog *fp)\n+{\n+\tif (fp-\u003ejited) {\n+\t\tstruct hppa_jit_data *jit_data = fp-\u003eaux-\u003ejit_data;\n+\t\tstruct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);\n+\n+\t\t/* Cleanup for earlier subprogs if jit_subprogs() aborts */\n+\t\tif (jit_data) {\n+\t\t\tkfree(jit_data-\u003ectx.offset);\n+\t\t\tkfree(jit_data);\n+\t\t}\n+\n+\t\tbpf_jit_binary_free(hdr);\n+\t\tWARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));\n+\t}\n+\n+\tbpf_prog_unlock_free(fp);\n+}\n+\n u64 hppa_div64(u64 div, u64 divisor)\n {\n \tdiv = div64_u64(div, divisor);\ndiff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c\nindex 7b07b43575f111..ff9bcd55165b49 100644\n--- a/arch/powerpc/net/bpf_jit_comp.c\n+++ b/arch/powerpc/net/bpf_jit_comp.c\n@@ -314,7 +314,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\tbpf_jit_build_prologue(code_base, \u0026cgctx);\n \t\tif (bpf_jit_build_body(fp, code_base, fcode_base, \u0026cgctx, addrs, pass,\n \t\t\t\t extra_pass)) {\n-\t\t\tbpf_arch_text_copy(\u0026fhdr-\u003esize, \u0026hdr-\u003esize, sizeof(hdr-\u003esize));\n \t\t\tbpf_jit_binary_pack_free(fhdr, hdr);\n \t\t\tgoto out_err;\n \t\t}\n@@ -339,8 +338,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n #endif\n \n \tif (!fp-\u003eis_func || extra_pass) {\n-\t\tif (bpf_jit_binary_pack_finalize(fhdr, hdr))\n+\t\tif (bpf_jit_binary_pack_finalize(fhdr, hdr)) {\n+\t\t\tbpf_jit_binary_pack_free(fhdr, NULL);\n \t\t\tgoto out_err;\n+\t\t}\n \t}\n \n \tfp-\u003ebpf_func = (void *)fimage;\ndiff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c\nindex cbfcd287ea1668..55530e80df2efb 100644\n--- a/arch/riscv/net/bpf_jit_core.c\n+++ b/arch/riscv/net/bpf_jit_core.c\n@@ -154,7 +154,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \n \tif (!prog-\u003eis_func || extra_pass) {\n \t\tif (WARN_ON(bpf_jit_binary_pack_finalize(jit_data-\u003ero_header, jit_data-\u003eheader))) {\n-\t\t\t/* ro_header has been freed */\n+\t\t\tbpf_jit_binary_pack_free(jit_data-\u003ero_header, NULL);\n \t\t\tjit_data-\u003ero_header = NULL;\n \t\t\tjit_data-\u003eheader = NULL;\n \t\t\tgoto out_free_hdr;\n@@ -183,11 +183,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\tprog-\u003ejited = 0;\n \t\tprog-\u003ejited_len = 0;\n \t}\n-\tif (jit_data-\u003eheader) {\n-\t\tbpf_arch_text_copy(\u0026jit_data-\u003ero_header-\u003esize, \u0026jit_data-\u003eheader-\u003esize,\n-\t\t\t\t sizeof(jit_data-\u003eheader-\u003esize));\n+\tif (jit_data-\u003eheader)\n \t\tbpf_jit_binary_pack_free(jit_data-\u003ero_header, jit_data-\u003eheader);\n-\t}\n \tgoto out_offset;\n }\n \n@@ -237,6 +234,7 @@ void bpf_jit_free(struct bpf_prog *prog)\n \t\t\tkvfree(jit_data-\u003ectx.offset);\n \t\t\tkfree(jit_data);\n \t\t}\n+\t\tprog-\u003ebpf_func = (void *)prog-\u003ebpf_func - cfi_get_offset();\n \t\thdr = bpf_jit_binary_pack_hdr(prog);\n \t\tbpf_jit_binary_pack_free(hdr, NULL);\n \t\tWARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));\ndiff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c\nindex b60877478b45d6..bf100e794e2784 100644\n--- a/arch/s390/net/bpf_jit_comp.c\n+++ b/arch/s390/net/bpf_jit_comp.c\n@@ -3106,3 +3106,22 @@ bool bpf_jit_inlines_helper_call(s32 imm)\n \t\treturn false;\n \t}\n }\n+\n+void bpf_jit_free(struct bpf_prog *fp)\n+{\n+\tif (fp-\u003ejited) {\n+\t\tstruct s390_jit_data *jit_data = fp-\u003eaux-\u003ejit_data;\n+\t\tstruct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);\n+\n+\t\t/* Cleanup for earlier subprogs if jit_subprogs() aborts */\n+\t\tif (jit_data) {\n+\t\t\tkvfree(jit_data-\u003ectx.addrs);\n+\t\t\tkfree(jit_data);\n+\t\t}\n+\n+\t\tbpf_jit_binary_free(hdr);\n+\t\tWARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));\n+\t}\n+\n+\tbpf_prog_unlock_free(fp);\n+}\ndiff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c\nindex 2fa0e93751276e..b5892cdce7113a 100644\n--- a/arch/sparc/net/bpf_jit_comp_64.c\n+++ b/arch/sparc/net/bpf_jit_comp_64.c\n@@ -1611,3 +1611,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t}\n \tgoto out_off;\n }\n+\n+void bpf_jit_free(struct bpf_prog *fp)\n+{\n+\tif (fp-\u003ejited) {\n+\t\tstruct sparc64_jit_data *jit_data = fp-\u003eaux-\u003ejit_data;\n+\t\tstruct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);\n+\n+\t\t/* Cleanup for earlier subprogs if jit_subprogs() aborts */\n+\t\tif (jit_data) {\n+\t\t\tkfree(jit_data-\u003ectx.offset);\n+\t\t\tkfree(jit_data);\n+\t\t}\n+\n+\t\tbpf_jit_binary_free(hdr);\n+\t\tWARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));\n+\t}\n+\n+\tbpf_prog_unlock_free(fp);\n+}\ndiff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c\nindex b2feec81e2312e..281e89764d9853 100644\n--- a/arch/x86/net/bpf_jit_comp.c\n+++ b/arch/x86/net/bpf_jit_comp.c\n@@ -3930,11 +3930,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\tif (proglen \u003c= 0) {\n out_image:\n \t\t\timage = NULL;\n-\t\t\tif (header) {\n-\t\t\t\tbpf_arch_text_copy(\u0026header-\u003esize, \u0026rw_header-\u003esize,\n-\t\t\t\t\t\t sizeof(rw_header-\u003esize));\n+\t\t\tif (header)\n \t\t\t\tbpf_jit_binary_pack_free(header, rw_header);\n-\t\t\t}\n \t\t\tif (extra_pass) {\n \t\t\t\tprog-\u003ebpf_func = NULL;\n \t\t\t\tprog-\u003ejited = 0;\n@@ -3987,7 +3984,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \t\t\t * Both cases are serious bugs and justify WARN_ON.\n \t\t\t */\n \t\t\tif (WARN_ON(bpf_jit_binary_pack_finalize(header, rw_header))) {\n-\t\t\t\t/* header has been freed */\n+\t\t\t\tbpf_jit_binary_pack_free(header, NULL);\n \t\t\t\theader = NULL;\n \t\t\t\tgoto out_image;\n \t\t\t}\ndiff --git a/include/linux/filter.h b/include/linux/filter.h\nindex 32d5297c557e5b..5d7fc70bd332e0 100644\n--- a/include/linux/filter.h\n+++ b/include/linux/filter.h\n@@ -1338,6 +1338,8 @@ void bpf_jit_free_exec(void *addr);\n void bpf_jit_free(struct bpf_prog *fp);\n struct bpf_binary_header *\n bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);\n+struct bpf_binary_header *\n+bpf_jit_binary_hdr(const struct bpf_prog *fp);\n \n void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic);\n void bpf_prog_pack_free(void *ptr, u32 size);\ndiff --git a/kernel/bpf/core.c b/kernel/bpf/core.c\nindex e2076667b24517..8d3528311f8eea 100644\n--- a/kernel/bpf/core.c\n+++ b/kernel/bpf/core.c\n@@ -1218,6 +1218,13 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,\n \t\treturn NULL;\n \t}\n \n+\t/* Initialize ro_header-\u003esize to ensure it is valid during free */\n+\tif (IS_ERR(bpf_arch_text_copy(\u0026ro_header-\u003esize, \u0026size, sizeof(size)))) {\n+\t\tbpf_prog_pack_free(ro_header, size);\n+\t\tbpf_jit_uncharge_modmem(size);\n+\t\treturn NULL;\n+\t}\n+\n \t*rw_header = kvmalloc(size, GFP_KERNEL);\n \tif (!*rw_header) {\n \t\tbpf_prog_pack_free(ro_header, size);\n@@ -1249,10 +1256,9 @@ int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header,\n \n \tkvfree(rw_header);\n \n-\tif (IS_ERR(ptr)) {\n-\t\tbpf_prog_pack_free(ro_header, ro_header-\u003esize);\n+\tif (IS_ERR(ptr))\n \t\treturn PTR_ERR(ptr);\n-\t}\n+\n \treturn 0;\n }\n \n@@ -1260,11 +1266,6 @@ int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header,\n * 1) when the program is freed after;\n * 2) when the JIT engine fails (before bpf_jit_binary_pack_finalize).\n * For case 2), we need to free both the RO memory and the RW buffer.\n- *\n- * bpf_jit_binary_pack_free requires proper ro_header-\u003esize. However,\n- * bpf_jit_binary_pack_alloc does not set it. Therefore, ro_header-\u003esize\n- * must be set with either bpf_jit_binary_pack_finalize (normal path) or\n- * bpf_arch_text_copy (when jit fails).\n */\n void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header,\n \t\t\t struct bpf_binary_header *rw_header)\n@@ -1286,7 +1287,7 @@ bpf_jit_binary_pack_hdr(const struct bpf_prog *fp)\n \treturn (void *)addr;\n }\n \n-static inline struct bpf_binary_header *\n+struct bpf_binary_header *\n bpf_jit_binary_hdr(const struct bpf_prog *fp)\n {\n \tunsigned long real_start = (unsigned long)fp-\u003ebpf_func;\n"
} |
| 2/1 | 2026/07/26 17:51 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"BPF_JIT",
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_jit_binary_pack_alloc",
"bpf_jit_binary_pack_finalize",
"bpf_jit_binary_pack_free",
"bpf_jit_binary_hdr",
"bpf_int_jit_compile",
"bpf_jit_free"
],
"Reasoning": "The patch fixes memory leaks and incorrect freeing of BPF JIT headers and data during JIT compilation failures or when freeing BPF programs. It modifies core BPF JIT memory management functions and architecture-specific JIT compilers. These changes are functional, reachable from user space via the bpf() syscall, and should be fuzzed to ensure no memory leaks or use-after-free issues occur during BPF program load/unload.",
"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 0bab7a5396f10cb242b6fea4e99338c0c1373d46
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Jul 26 17:51:35 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c
index 639a2736f029ed..29c8933e2dd2ce 100644
--- a/arch/arc/net/bpf_jit_core.c
+++ b/arch/arc/net/bpf_jit_core.c
@@ -1412,3 +1412,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
return prog;
}
+
+void bpf_jit_free(struct bpf_prog *fp)
+{
+ if (fp->jited) {
+ struct arc_jit_data *jit_data = fp->aux->jit_data;
+ struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
+
+ /* Cleanup for earlier subprogs if jit_subprogs() aborts */
+ if (jit_data) {
+ kfree(jit_data->bpf2insn);
+ kfree(jit_data);
+ }
+
+ bpf_jit_binary_free(hdr);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
+ }
+
+ bpf_prog_unlock_free(fp);
+}
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 4cdc7dfb05ba9a..32780247305eb0 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -2258,7 +2258,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
goto out_free_hdr;
}
if (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) {
- /* ro_header and header has been freed */
+ bpf_jit_binary_pack_free(ro_header, NULL);
ro_header = NULL;
header = NULL;
goto out_free_hdr;
@@ -2308,9 +2308,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
prog->jited_len = 0;
}
if (header) {
- bpf_arch_text_copy(&ro_header->size, &header->size,
- sizeof(header->size));
bpf_jit_binary_pack_free(ro_header, header);
+ ro_header = NULL;
}
goto out_off;
}
@@ -3237,6 +3236,7 @@ void bpf_jit_free(struct bpf_prog *prog)
*/
if (jit_data) {
bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
+ kvfree(jit_data->ctx.offset);
kfree(jit_data);
}
prog->bpf_func = (void *)prog->bpf_func - cfi_get_offset();
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 2738b4db116533..48ad418df1331a 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -2298,7 +2298,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
goto out_free;
}
if (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) {
- /* ro_header and header have been freed */
+ bpf_jit_binary_pack_free(ro_header, NULL);
ro_header = NULL;
header = NULL;
goto out_free;
@@ -2341,10 +2341,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
prog->jited_len = 0;
}
- if (header) {
- bpf_arch_text_copy(&ro_header->size, &header->size, sizeof(header->size));
+ if (header)
bpf_jit_binary_pack_free(ro_header, header);
- }
goto out_offset;
}
diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c
index 172770132440db..ef63c38bdf1510 100644
--- a/arch/parisc/net/bpf_jit_core.c
+++ b/arch/parisc/net/bpf_jit_core.c
@@ -178,6 +178,25 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
goto out_offset;
}
+void bpf_jit_free(struct bpf_prog *fp)
+{
+ if (fp->jited) {
+ struct hppa_jit_data *jit_data = fp->aux->jit_data;
+ struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
+
+ /* Cleanup for earlier subprogs if jit_subprogs() aborts */
+ if (jit_data) {
+ kfree(jit_data->ctx.offset);
+ kfree(jit_data);
+ }
+
+ bpf_jit_binary_free(hdr);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
+ }
+
+ bpf_prog_unlock_free(fp);
+}
+
u64 hppa_div64(u64 div, u64 divisor)
{
div = div64_u64(div, divisor);
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 7b07b43575f111..ff9bcd55165b49 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -314,7 +314,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
bpf_jit_build_prologue(code_base, &cgctx);
if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass,
extra_pass)) {
- bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size));
bpf_jit_binary_pack_free(fhdr, hdr);
goto out_err;
}
@@ -339,8 +338,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
#endif
if (!fp->is_func || extra_pass) {
- if (bpf_jit_binary_pack_finalize(fhdr, hdr))
+ if (bpf_jit_binary_pack_finalize(fhdr, hdr)) {
+ bpf_jit_binary_pack_free(fhdr, NULL);
goto out_err;
+ }
}
fp->bpf_func = (void *)fimage;
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index cbfcd287ea1668..55530e80df2efb 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -154,7 +154,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
if (!prog->is_func || extra_pass) {
if (WARN_ON(bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header))) {
- /* ro_header has been freed */
+ bpf_jit_binary_pack_free(jit_data->ro_header, NULL);
jit_data->ro_header = NULL;
jit_data->header = NULL;
goto out_free_hdr;
@@ -183,11 +183,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
prog->jited = 0;
prog->jited_len = 0;
}
- if (jit_data->header) {
- bpf_arch_text_copy(&jit_data->ro_header->size, &jit_data->header->size,
- sizeof(jit_data->header->size));
+ if (jit_data->header)
bpf_jit_binary_pack_free(jit_data->ro_header, jit_data->header);
- }
goto out_offset;
}
@@ -237,6 +234,7 @@ void bpf_jit_free(struct bpf_prog *prog)
kvfree(jit_data->ctx.offset);
kfree(jit_data);
}
+ prog->bpf_func = (void *)prog->bpf_func - cfi_get_offset();
hdr = bpf_jit_binary_pack_hdr(prog);
bpf_jit_binary_pack_free(hdr, NULL);
WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index b60877478b45d6..bf100e794e2784 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -3106,3 +3106,22 @@ bool bpf_jit_inlines_helper_call(s32 imm)
return false;
}
}
+
+void bpf_jit_free(struct bpf_prog *fp)
+{
+ if (fp->jited) {
+ struct s390_jit_data *jit_data = fp->aux->jit_data;
+ struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
+
+ /* Cleanup for earlier subprogs if jit_subprogs() aborts */
+ if (jit_data) {
+ kvfree(jit_data->ctx.addrs);
+ kfree(jit_data);
+ }
+
+ bpf_jit_binary_free(hdr);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
+ }
+
+ bpf_prog_unlock_free(fp);
+}
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index 2fa0e93751276e..b5892cdce7113a 100644
--- a/arch/sparc/net/bpf_jit_comp_64.c
+++ b/arch/sparc/net/bpf_jit_comp_64.c
@@ -1611,3 +1611,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
}
goto out_off;
}
+
+void bpf_jit_free(struct bpf_prog *fp)
+{
+ if (fp->jited) {
+ struct sparc64_jit_data *jit_data = fp->aux->jit_data;
+ struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
+
+ /* Cleanup for earlier subprogs if jit_subprogs() aborts */
+ if (jit_data) {
+ kfree(jit_data->ctx.offset);
+ kfree(jit_data);
+ }
+
+ bpf_jit_binary_free(hdr);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
+ }
+
+ bpf_prog_unlock_free(fp);
+}
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index b2feec81e2312e..281e89764d9853 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -3930,11 +3930,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
if (proglen <= 0) {
out_image:
image = NULL;
- if (header) {
- bpf_arch_text_copy(&header->size, &rw_header->size,
- sizeof(rw_header->size));
+ if (header)
bpf_jit_binary_pack_free(header, rw_header);
- }
if (extra_pass) {
prog->bpf_func = NULL;
prog->jited = 0;
@@ -3987,7 +3984,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
* Both cases are serious bugs and justify WARN_ON.
*/
if (WARN_ON(bpf_jit_binary_pack_finalize(header, rw_header))) {
- /* header has been freed */
+ bpf_jit_binary_pack_free(header, NULL);
header = NULL;
goto out_image;
}
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 32d5297c557e5b..5d7fc70bd332e0 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1338,6 +1338,8 @@ void bpf_jit_free_exec(void *addr);
void bpf_jit_free(struct bpf_prog *fp);
struct bpf_binary_header *
bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
+struct bpf_binary_header *
+bpf_jit_binary_hdr(const struct bpf_prog *fp);
void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic);
void bpf_prog_pack_free(void *ptr, u32 size);
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index e2076667b24517..8d3528311f8eea 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1218,6 +1218,13 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,
return NULL;
}
+ /* Initialize ro_header->size to ensure it is valid during free */
+ if (IS_ERR(bpf_arch_text_copy(&ro_header->size, &size, sizeof(size)))) {
+ bpf_prog_pack_free(ro_header, size);
+ bpf_jit_uncharge_modmem(size);
+ return NULL;
+ }
+
*rw_header = kvmalloc(size, GFP_KERNEL);
if (!*rw_header) {
bpf_prog_pack_free(ro_header, size);
@@ -1249,10 +1256,9 @@ int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header,
kvfree(rw_header);
- if (IS_ERR(ptr)) {
- bpf_prog_pack_free(ro_header, ro_header->size);
+ if (IS_ERR(ptr))
return PTR_ERR(ptr);
- }
+
return 0;
}
@@ -1260,11 +1266,6 @@ int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header,
* 1) when the program is freed after;
* 2) when the JIT engine fails (before bpf_jit_binary_pack_finalize).
* For case 2), we need to free both the RO memory and the RW buffer.
- *
- * bpf_jit_binary_pack_free requires proper ro_header->size. However,
- * bpf_jit_binary_pack_alloc does not set it. Therefore, ro_header->size
- * must be set with either bpf_jit_binary_pack_finalize (normal path) or
- * bpf_arch_text_copy (when jit fails).
*/
void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header,
struct bpf_binary_header *rw_header)
@@ -1286,7 +1287,7 @@ bpf_jit_binary_pack_hdr(const struct bpf_prog *fp)
return (void *)addr;
}
-static inline struct bpf_binary_header *
+struct bpf_binary_header *
bpf_jit_binary_hdr(const struct bpf_prog *fp)
{
unsigned long real_start = (unsigned long)fp->bpf_func;
|
| 3/2 | 2026/07/26 17:51 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6826 output: 24 thoughts: 656 Thoughts: **Analyzing a BPF JIT Compilation Patch** Alright, let's break down this patch. My initial impression is that it's dealing with crucial memory management issues within the BPF JIT compiler, specifically related to how we handle JIT headers and data when there are compilation failures or during the unloading of BPF programs. It appears that the patch addresses missing or incorrect `bpf_jit_free` implementations for a number of architectures – arc, parisc, s390, and sparc are mentioned as having new implementations, or needing updates. This implies that these architectures were either using a default, possibly less efficient, freeing mechanism, or didn't handle failures correctly. For the arm64, loongarch, powerpc, riscv, and x86 architectures, the changes seem to focus on refining the error handling within `bpf_int_jit_compile`. The core functionality being targeted is undoubtedly reachable. BPF JIT is fundamental, and user space interacts with it through the `bpf()` syscall when loading programs. So, we're talking about a change that will impact how memory is managed during both program loading and unloading. My key focus, now, needs to be on identifying the core symbols involved. I can see that the changes touch on `bpf_int_jit_compile` and `bpf_jit_free`, which are crucial in many architectures. I also see calls to functions like `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, `bpf_jit_binary_pack_free`, and `bpf_jit_binary_hdr`. These are all clearly involved in managing the allocated binary data within the JIT process. It's a bit of a detail, but it is clear that `bpf_int_jit_compile` is architecture specific. Looking at `kernel/bpf/core.c`, I'm confirming that `bpf_jit_binary_pack_alloc` is exported or used by the JIT implementations, and that `bpf_jit_free` is called when a BPF program is freed, just as I'd expect. The key functions to focus on are really `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, `bpf_jit_binary_pack_free`, `bpf_jit_free`, and `bpf_int_jit_compile`. I need to remember, when reviewing, that `bpf_int_jit_compile` is architecture specific. Finally, I need to ensure that the necessary kernel configurations are in place. Obviously, `CONFIG_BPF_JIT` is a must. And from experience, that's usually enabled by default on many architectures, so I'll double-check `kernel/bpf/Kconfig`. And of course, I'll need to use my usual verification tools to make sure everything's correct and that I haven't missed anything. |
| 4/2 | 2026/07/26 17:51 | tool | grepper |
0mArgs:{
"Expression": "bpf_jit_binary_pack_alloc"
}Results: {
"Output": "arch/arm64/net/bpf_jit_comp.c=2093=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/arm64/net/bpf_jit_comp.c-2190-\timage_size = extable_offset + extable_size;\narch/arm64/net/bpf_jit_comp.c:2191:\tro_header = bpf_jit_binary_pack_alloc(image_size, \u0026ro_image_ptr,\narch/arm64/net/bpf_jit_comp.c-2192-\t\t\t\t\t sizeof(u64), \u0026header, \u0026image_ptr,\n--\narch/loongarch/net/bpf_jit.c=2197=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/loongarch/net/bpf_jit.c-2257-\t/* Now we know the size of the structure to make */\narch/loongarch/net/bpf_jit.c:2258:\tro_header = bpf_jit_binary_pack_alloc(image_size, \u0026ro_image_ptr, sizeof(u32),\narch/loongarch/net/bpf_jit.c-2259-\t\t\t\t\t \u0026header, \u0026image_ptr, jit_fill_hole,\n--\narch/powerpc/net/bpf_jit_comp.c=165=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *fp)\n--\narch/powerpc/net/bpf_jit_comp.c-296-\narch/powerpc/net/bpf_jit_comp.c:297:\tfhdr = bpf_jit_binary_pack_alloc(alloclen, \u0026fimage, 4, \u0026hdr, \u0026image,\narch/powerpc/net/bpf_jit_comp.c-298-\t\t\t\t\t bpf_jit_fill_ill_insns, bpf_prog_was_classic(fp));\n--\narch/riscv/net/bpf_jit_core.c=44=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/riscv/net/bpf_jit_core.c-108-\t\t\tjit_data-\u003ero_header =\narch/riscv/net/bpf_jit_core.c:109:\t\t\t\tbpf_jit_binary_pack_alloc(prog_size + extable_size,\narch/riscv/net/bpf_jit_core.c-110-\t\t\t\t\t\t\t \u0026jit_data-\u003ero_image, sizeof(u32),\n--\narch/x86/net/bpf_jit_comp.c=3850=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/x86/net/bpf_jit_comp.c-3961-\t\t\t/* allocate module memory for x86 insns and extable */\narch/x86/net/bpf_jit_comp.c:3962:\t\t\theader = bpf_jit_binary_pack_alloc(roundup(proglen, align) + extable_size,\narch/x86/net/bpf_jit_comp.c-3963-\t\t\t\t\t\t\t \u0026image, align, \u0026rw_header, \u0026rw_image,\n--\ninclude/linux/filter.h=1353=struct bpf_binary_header *\ninclude/linux/filter.h:1354:bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **ro_image,\ninclude/linux/filter.h-1355-\t\t\t unsigned int alignment,\n--\nkernel/bpf/core.c=1196=struct bpf_binary_header *\nkernel/bpf/core.c:1197:bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,\nkernel/bpf/core.c-1198-\t\t\t unsigned int alignment,\n"
} |
| 5/2 | 2026/07/26 17:51 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9221 output: 20 thoughts: 268 Thoughts: **My Analysis of this BPF JIT Patch** Okay, so this patch is clearly making some significant changes to the BPF JIT compilation process. I see it's touching `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, and `bpf_jit_binary_pack_free` within `kernel/bpf/core.c`. This immediately piques my interest, as that's the core of how the JIT binaries are handled. It also extends to `bpf_int_jit_compile` and `bpf_jit_free` across multiple architectures, so this seems pretty far-reaching. Given the scope of the modifications, and specifically those functions, this is absolutely something that warrants thorough fuzzing. The key symbols I'm going to focus on are `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, `bpf_jit_binary_pack_free`, and also `bpf_jit_binary_hdr`, as those seem like the most critical points. Ah, good, it looks like `bpf_jit_binary_hdr` was previously static and is now being exported. I'll need to remember that. It’s an important detail. Now, let's see about the configuration requirements. I'm assuming `CONFIG_BPF_JIT` is going to be a requirement here. A quick check of `kernel/bpf/Kconfig` will confirm that. I need to make sure the build environment is set correctly to enable these new changes. |
| 6/2 | 2026/07/26 17:51 | tool | grepper |
0mArgs:{
"Expression": "config BPF_JIT"
}Results: {
"Output": "kernel/bpf/Kconfig=27=config BPF_SYSCALL\n--\nkernel/bpf/Kconfig-41-\nkernel/bpf/Kconfig:42:config BPF_JIT\nkernel/bpf/Kconfig-43-\tbool \"Enable BPF Just In Time compiler\"\n--\nkernel/bpf/Kconfig-57-\nkernel/bpf/Kconfig:58:config BPF_JIT_ALWAYS_ON\nkernel/bpf/Kconfig-59-\tbool \"Permanently enable BPF JIT and remove BPF interpreter\"\n--\nkernel/bpf/Kconfig-68-\nkernel/bpf/Kconfig:69:config BPF_JIT_DEFAULT_ON\nkernel/bpf/Kconfig-70-\tdef_bool ARCH_WANT_DEFAULT_BPF_JIT || BPF_JIT_ALWAYS_ON\n"
} |
| 7/2 | 2026/07/26 17:51 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10077 output: 38 thoughts: 126 Thoughts: **Analyzing the BPF JIT Configuration** Okay, so I'm looking at this patch and immediately, my focus goes to the BPF JIT configuration. Seems like `BPF_JIT` is the critical one, as expected. I'll need to double-check that `BPF_SYSCALL` is enabled too, although that one's usually taken care of. The file modifications point directly to `BPF_JIT` being the primary focus here. I see changes in the architecture-specific JIT compilation files like `arch/x86/net/bpf_jit_comp.c` and `arch/arm64/net/bpf_jit_comp.c`. That further reinforces the importance of `BPF_JIT`. Now, I should investigate the memory allocation process, especially `bpf_jit_binary_pack_alloc` within `kernel/bpf/core.c`. Let's see how that's impacted. |
| 8/2 | 2026/07/26 17:52 | tool | grepper |
0mArgs:{
"Expression": "bpf_jit_binary_pack_alloc",
"PathPrefix": "kernel/bpf/core.c"
}Results: {
"Output": "kernel/bpf/core.c=1196=struct bpf_binary_header *\nkernel/bpf/core.c:1197:bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,\nkernel/bpf/core.c-1198-\t\t\t unsigned int alignment,\n"
} |
| 9/2 | 2026/07/26 17:52 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10547 output: 22 thoughts: 498 Thoughts: **Focusing on BPF JIT Compilation & Freeing** Okay, let's zero in on the key functions for this. I need to examine `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, `bpf_jit_binary_pack_free`, and `bpf_jit_binary_hdr`. Are there any others that merit attention? Ah, yes, `bpf_jit_free` is modified in quite a few architecture-specific files: `arch/arc/net/bpf_jit_core.c`, `arch/arm64/net/bpf_jit_comp.c`, and so on. Similarly, `bpf_int_jit_compile` has multiple architecture-specific implementations. Since they're architecture-specific, `bpf_int_jit_compile` and `bpf_jit_free` are excellent candidates for deeper investigation. They represent crucial points where the JIT process can diverge based on the target architecture. Now, while `bpf_int_jit_compile` looks like it might be a performance bottleneck during program load, it's actually exactly what we want to fuzz – the BPF program load process. It's a control path, not a hot path in the data path. So, both `bpf_int_jit_compile` and `bpf_jit_free` are solid picks. I should verify if `bpf_jit_free` is defined as a weak function in `kernel/bpf/core.c` or purely architecture-specific. That will influence how I approach the fuzzing. |
| 10/2 | 2026/07/26 17:52 | tool | grepper |
0mArgs:{
"Expression": "void bpf_jit_free\\("
}Results: {
"Output": "arch/arc/net/bpf_jit_core.c=1403=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/arc/net/bpf_jit_core.c-1415-\narch/arc/net/bpf_jit_core.c:1416:void bpf_jit_free(struct bpf_prog *fp)\narch/arc/net/bpf_jit_core.c-1417-{\n--\narch/arm64/net/bpf_jit_comp.c=3212=bool bpf_jit_inlines_helper_call(s32 imm)\n--\narch/arm64/net/bpf_jit_comp.c-3223-\narch/arm64/net/bpf_jit_comp.c:3224:void bpf_jit_free(struct bpf_prog *prog)\narch/arm64/net/bpf_jit_comp.c-3225-{\n--\narch/loongarch/net/bpf_jit.c=2197=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/loongarch/net/bpf_jit.c-2348-\narch/loongarch/net/bpf_jit.c:2349:void bpf_jit_free(struct bpf_prog *prog)\narch/loongarch/net/bpf_jit.c-2350-{\n--\narch/parisc/net/bpf_jit_core.c=44=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/parisc/net/bpf_jit_core.c-180-\narch/parisc/net/bpf_jit_core.c:181:void bpf_jit_free(struct bpf_prog *fp)\narch/parisc/net/bpf_jit_core.c-182-{\n--\narch/powerpc/net/bpf_jit_comp.c=463=int bpf_arch_text_invalidate(void *dst, size_t len)\n--\narch/powerpc/net/bpf_jit_comp.c-477-\narch/powerpc/net/bpf_jit_comp.c:478:void bpf_jit_free(struct bpf_prog *fp)\narch/powerpc/net/bpf_jit_comp.c-479-{\n--\narch/riscv/net/bpf_jit_core.c=210=int bpf_arch_text_invalidate(void *dst, size_t len)\n--\narch/riscv/net/bpf_jit_core.c-220-\narch/riscv/net/bpf_jit_core.c:221:void bpf_jit_free(struct bpf_prog *prog)\narch/riscv/net/bpf_jit_core.c-222-{\n--\narch/s390/net/bpf_jit_comp.c=3098=bool bpf_jit_inlines_helper_call(s32 imm)\n--\narch/s390/net/bpf_jit_comp.c-3109-\narch/s390/net/bpf_jit_comp.c:3110:void bpf_jit_free(struct bpf_prog *fp)\narch/s390/net/bpf_jit_comp.c-3111-{\n--\narch/sparc/net/bpf_jit_comp_32.c=652=cond_branch:\t\t\tf_offset = addrs[i + filter[i].jf];\n--\narch/sparc/net/bpf_jit_comp_32.c-757-\narch/sparc/net/bpf_jit_comp_32.c:758:void bpf_jit_free(struct bpf_prog *fp)\narch/sparc/net/bpf_jit_comp_32.c-759-{\n--\narch/sparc/net/bpf_jit_comp_64.c=1480=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/sparc/net/bpf_jit_comp_64.c-1614-\narch/sparc/net/bpf_jit_comp_64.c:1615:void bpf_jit_free(struct bpf_prog *fp)\narch/sparc/net/bpf_jit_comp_64.c-1616-{\n--\narch/x86/net/bpf_jit_comp.c=4062=bool bpf_jit_supports_percpu_insn(void)\n--\narch/x86/net/bpf_jit_comp.c-4066-\narch/x86/net/bpf_jit_comp.c:4067:void bpf_jit_free(struct bpf_prog *prog)\narch/x86/net/bpf_jit_comp.c-4068-{\n--\ninclude/linux/filter.h=1337=void bpf_jit_free_exec(void *addr);\ninclude/linux/filter.h:1338:void bpf_jit_free(struct bpf_prog *fp);\ninclude/linux/filter.h-1339-struct bpf_binary_header *\n--\ninclude/linux/filter.h=1473=bpf_jit_add_poke_descriptor(struct bpf_prog *prog,\n--\ninclude/linux/filter.h-1478-\ninclude/linux/filter.h:1479:static inline void bpf_jit_free(struct bpf_prog *fp)\ninclude/linux/filter.h-1480-{\n"
} |
| 11/2 | 2026/07/26 17:52 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12944 output: 205 thoughts: 528 Thoughts: **My Analysis of the BPF JIT Patch** Alright, let's break this down. From what I'm seeing, `bpf_jit_free` and `bpf_int_jit_compile` are implemented across all the architectures we're concerned with, which is a good starting point. The core memory management functions, `bpf_jit_binary_pack_alloc`, `bpf_jit_binary_pack_finalize`, `bpf_jit_binary_pack_free`, and `bpf_jit_binary_hdr` reside in `kernel/bpf/core.c`. My focus symbols, based on the diff, are going to be: * `bpf_jit_binary_pack_alloc` * `bpf_jit_binary_pack_finalize` * `bpf_jit_binary_pack_free` * `bpf_jit_binary_hdr` * `bpf_int_jit_compile` * `bpf_jit_free` The necessary config is definitely `BPF_JIT`. And let's not forget the basics: `CONFIG_BPF_SYSCALL` is essential for loading BPF programs. So, I'll be sure to include both `BPF_JIT` and `BPF_SYSCALL` in the checks. Now, let's recap the patch's purpose. It's about fixing memory leaks and incorrect freeing of BPF JIT headers and data. This happens during JIT compilation failures or when BPF programs are unloaded. The patch is touching core BPF JIT memory management and architecture-specific JIT compilers. This is all functional, user-space accessible via the `bpf()` syscall. This is going to need fuzzing to ensure there are no memory leaks or use-after-free conditions during load/unload operations. I'm thinking about `bpf_jit_binary_hdr` – is it worth a dedicated focus? It's a small helper function. From looking at it, it's pretty straightforward: it extracts the header. While it's simple, it's part of the picture, so I'll include it. Okay, let me double-check `bpf_jit_binary_pack_alloc` is exported; yep, it's in core.c and architecture JITs use it. Right, I'm confident with this. I will set the results. |
| 12/2 | 2026/07/26 17:52 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_JIT",
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_jit_binary_pack_alloc",
"bpf_jit_binary_pack_finalize",
"bpf_jit_binary_pack_free",
"bpf_jit_binary_hdr",
"bpf_int_jit_compile",
"bpf_jit_free"
],
"Reasoning": "The patch fixes memory leaks and incorrect freeing of BPF JIT headers and data during JIT compilation failures or when freeing BPF programs. It modifies core BPF JIT memory management functions and architecture-specific JIT compilers. These changes are functional, reachable from user space via the bpf() syscall, and should be fuzzed to ensure no memory leaks or use-after-free issues occur during BPF program load/unload.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_JIT",
"BPF_SYSCALL"
],
"FocusSymbols": [
"bpf_jit_binary_pack_alloc",
"bpf_jit_binary_pack_finalize",
"bpf_jit_binary_pack_free",
"bpf_jit_binary_hdr",
"bpf_int_jit_compile",
"bpf_jit_free"
],
"Reasoning": "The patch fixes memory leaks and incorrect freeing of BPF JIT headers and data during JIT compilation failures or when freeing BPF programs. It modifies core BPF JIT memory management functions and architecture-specific JIT compilers. These changes are functional, reachable from user space via the bpf() syscall, and should be fuzzed to ensure no memory leaks or use-after-free issues occur during BPF program load/unload.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|