* [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free
@ 2026-07-25 10:20 Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
` (6 more replies)
0 siblings, 7 replies; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
Fixes for bpf_jit_free identified by Sashiko, as previously noted in [0].
Link: https://lore.kernel.org/bpf/28ba19a4-b487-49fd-bbba-04410acdb113@iogearbox.net/ [0]
v2:
- Fix JITs not freeing leftover jit_data when jit_subprogs() aborts. (Sashiko)
- Drop fix for loongarch as it's applied.
v1: https://lore.kernel.org/bpf/20260722112754.1615201-1-pulehui@huaweicloud.com
Pu Lehui (7):
bpf, arm64: Fix memory leak in bpf_jit_free
s390/bpf: Fix memory leak in bpf_jit_free
parisc: Fix memory leak in bpf_jit_free
bpf, sparc64: Fix memory leak in bpf_jit_free
ARC, bpf: Fix memory leak in bpf_jit_free
riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
bpf: Fix double-free RO header in bpf_jit_free
arch/arc/net/bpf_jit_core.c | 19 +++++++++++++++++++
arch/arm64/net/bpf_jit_comp.c | 8 +++-----
arch/loongarch/net/bpf_jit.c | 6 ++----
arch/parisc/net/bpf_jit_core.c | 19 +++++++++++++++++++
arch/powerpc/net/bpf_jit_comp.c | 5 +++--
arch/riscv/net/bpf_jit_core.c | 8 +++-----
arch/s390/net/bpf_jit_comp.c | 19 +++++++++++++++++++
arch/sparc/net/bpf_jit_comp_64.c | 19 +++++++++++++++++++
arch/x86/net/bpf_jit_comp.c | 7 ++-----
kernel/bpf/core.c | 17 +++++++++--------
10 files changed, 98 insertions(+), 29 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:31 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 2/7] s390/bpf: " Pu Lehui
` (5 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
When bpf_int_jit_compile() is called for subprograms, it returns early
during the first pass (!prog->is_func || extra_pass is false), keeping
ctx->offset alive for the subsequent extra pass.
If JIT compilation fails for a later subprogram, the BPF core aborts and
calls bpf_jit_free() to clean up the first subprogram. However,
bpf_jit_free() fails to free jit_data->ctx.offset, which causes a memory
leak of the JIT context offsets array.
Fix this by adding the missing kvfree(jit_data->ctx.offset) in
bpf_jit_free().
Fixes: 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory management")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Acked-by: Xu Kuohai <xukuohai@huawei.com>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/arm64/net/bpf_jit_comp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 4cdc7dfb05ba..f4e4d4578e38 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -3237,6 +3237,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();
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 2/7] s390/bpf: Fix memory leak in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:27 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 3/7] parisc: " Pu Lehui
` (4 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
If a subprogram fails to JIT in jit_subprogs(), previously JITed
subprograms are freed. However, the generic bpf_jit_free() fails to
free their leftover jit_data, causing a memory leak.
Implement a custom bpf_jit_free() to free this data.
Fixes: 1c8f9b91c456 ("bpf: s390: add JIT support for multi-function programs")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/s390/net/bpf_jit_comp.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index b60877478b45..d9fdb32b7a96 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 bpf_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);
+}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 3/7] parisc: Fix memory leak in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 2/7] s390/bpf: " Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:28 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 4/7] bpf, sparc64: " Pu Lehui
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
If a subprogram fails to JIT in jit_subprogs(), previously JITed
subprograms are freed. However, the generic bpf_jit_free() fails to
free their leftover jit_data, causing a memory leak.
Implement a custom bpf_jit_free() to free this data.
Fixes: 22de5d626231 ("parisc: Add eBPF JIT compiler glue code and Makefile")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/parisc/net/bpf_jit_core.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c
index 172770132440..11e13ad6bc50 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 bpf_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);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 4/7] bpf, sparc64: Fix memory leak in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
` (2 preceding siblings ...)
2026-07-25 10:20 ` [PATCH bpf-next v2 3/7] parisc: " Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:29 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 5/7] ARC, bpf: " Pu Lehui
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
If a subprogram fails to JIT in jit_subprogs(), previously JITed
subprograms are freed. However, the generic bpf_jit_free() fails to
free their leftover jit_data, causing a memory leak.
Implement a custom bpf_jit_free() to free this data.
Fixes: 5f5a64111639 ("bpf: sparc64: Add JIT support for multi-function programs.")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/sparc/net/bpf_jit_comp_64.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index 2fa0e9375127..3b72ff2dba9c 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 bpf_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);
+}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 5/7] ARC, bpf: Fix memory leak in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
` (3 preceding siblings ...)
2026-07-25 10:20 ` [PATCH bpf-next v2 4/7] bpf, sparc64: " Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:29 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 7/7] bpf: Fix double-free RO header " Pu Lehui
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
If a subprogram fails to JIT in jit_subprogs(), previously JITed
subprograms are freed. However, the generic bpf_jit_free() fails to
free their leftover jit_data, causing a memory leak.
Implement a custom bpf_jit_free() to free this data.
Fixes: f122668ddcce ("ARC: Add eBPF JIT support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/arc/net/bpf_jit_core.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c
index 639a2736f029..45a700f42cd4 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 bpf_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);
+}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
` (4 preceding siblings ...)
2026-07-25 10:20 ` [PATCH bpf-next v2 5/7] ARC, bpf: " Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
2026-07-25 10:27 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 7/7] bpf: Fix double-free RO header " Pu Lehui
6 siblings, 1 reply; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
When CFI is enabled, the actual BPF program entry point is shifted
forward by a CFI preamble. During bpf_jit_free(), this shifted pointer
causes the wrong ro_header to be fetched, leading to a potential invalid
memory free.
Fix this by subtracting cfi_get_offset() from prog->bpf_func to
correctly restore the original JITed allocation address before freeing.
Fixes: e63985ecd226 ("bpf, riscv64/cfi: Support kCFI + BPF on riscv64")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/riscv/net/bpf_jit_core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index cbfcd287ea16..059db1adeaf8 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -237,6 +237,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));
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next v2 7/7] bpf: Fix double-free RO header in bpf_jit_free
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
` (5 preceding siblings ...)
2026-07-25 10:20 ` [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
@ 2026-07-25 10:20 ` Pu Lehui
6 siblings, 0 replies; 14+ messages in thread
From: Pu Lehui @ 2026-07-25 10:20 UTC (permalink / raw)
To: bpf, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Yonghong Song, Song Liu, Jiri Olsa, Emil Tsalapatis,
Björn Töpel, Puranjay Mohan, Xu Kuohai, Tiezhu Yang,
Hengqi Chen, Huacai Chen, Ilya Leoshkevich, Heiko Carstens,
Vasily Gorbik, Helge Deller, David S. Miller, Shahab Vahedi,
Hari Bathini, Christophe Leroy (CS GROUP), Naveen N Rao, Pu Lehui,
Pu Lehui
From: Pu Lehui <pulehui@huawei.com>
When bpf_jit_binary_pack_finalize fails in bpf_jit_free, it implicitly
frees ro_header. However, JITs are unaware of this. They extract and
free it again, leading to double-free issue.
bpf_jit_free
bpf_jit_binary_pack_finalize(ro_header, rw_header)
ptr = bpf_arch_text_copy(ro_header, rw_header, rw_header->size);
kvfree(rw_header);
if (IS_ERR(ptr)) { <-- copy failed
bpf_prog_pack_free(ro_header, ro_header->size); <-- first free ro_header
return PTR_ERR(ptr);
}
hdr = bpf_jit_binary_pack_hdr(prog); <-- fetch ro_header
bpf_jit_binary_pack_free(hdr, NULL); <-- double free ro_header
Fix this by dropping the implicit free in bpf_jit_binary_pack_finalize.
Accordingly, adapt the JITs to explicitly handle freeing ro_header in
their error paths. This also fixes the missing memory uncharge upon
failure, as bpf_prog_pack_free does not uncharge.
Additionally, initialize ro_header->size in bpf_jit_binary_pack_alloc to
ensures ro_header->size is always valid during free, and remove
unnecessary bpf_arch_text_copy in JITs.
Fixes: 1d5f82d9dd47 ("bpf, x86: fix freeing of not-finalized bpf_prog_pack")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/arm64/net/bpf_jit_comp.c | 7 ++-----
arch/loongarch/net/bpf_jit.c | 6 ++----
arch/powerpc/net/bpf_jit_comp.c | 5 +++--
arch/riscv/net/bpf_jit_core.c | 7 ++-----
arch/x86/net/bpf_jit_comp.c | 7 ++-----
kernel/bpf/core.c | 17 +++++++++--------
6 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index f4e4d4578e38..f5851e08e76e 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;
@@ -2307,11 +2307,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
prog->jited = 0;
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_off;
}
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 2738b4db1165..48ad418df133 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/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 7b07b43575f1..ff9bcd55165b 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 059db1adeaf8..55530e80df2e 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;
}
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index b2feec81e231..281e89764d98 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/kernel/bpf/core.c b/kernel/bpf/core.c
index e2076667b245..00c32539f074 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)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
@ 2026-07-25 10:27 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:27 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] bpf_jit_free() ignores the return value of bpf_jit_binary_pack_finalize(), leading to a double free and use-after-free of the ro_header if finalization fails.
--
--- Patch [6]: [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free ---
commit 3086c59fad7254d5809adea2a09ea130ccb95d10
Author: Pu Lehui <pulehui@huawei.com>
riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
This commit subtracts cfi_get_offset() from prog->bpf_func to correctly
restore the original JITed allocation address before freeing it. This prevents
potential invalid memory frees when CFI is enabled.
> diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
> index cbfcd287ea166..059db1adeaf8d 100644
> --- a/arch/riscv/net/bpf_jit_core.c
> +++ b/arch/riscv/net/bpf_jit_core.c
> @@ -237,6 +237,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);
[Severity: Critical]
This is a pre-existing issue, but does ignoring the return value of
bpf_jit_binary_pack_finalize() called just above this block lead to a double
free?
If bpf_jit_binary_pack_finalize() fails during text patching, it frees the
ro_header internally and returns an error.
Since that error is ignored in bpf_jit_free(), the execution unconditionally
continues down to:
hdr = bpf_jit_binary_pack_hdr(prog);
bpf_jit_binary_pack_free(hdr, NULL);
Can this lead to a use-after-free when bpf_jit_binary_pack_free() tries to
read the header size, followed by a double free of the memory chunk?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=6
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 2/7] s390/bpf: Fix memory leak in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 2/7] s390/bpf: " Pu Lehui
@ 2026-07-25 10:27 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:27 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The patch introduces a direct compilation error on s390 by declaring and dereferencing an undefined struct `struct bpf_jit_data`.
--
--- Patch [2]: [PATCH bpf-next v2 2/7] s390/bpf: Fix memory leak in bpf_jit_free ---
commit 69c0bb88eff440919ad293e92f90d3f1f44abf60
Author: Pu Lehui <pulehui@huawei.com>
s390/bpf: Fix memory leak in bpf_jit_free
This commit implements a custom bpf_jit_free() for s390 to clean up leftover
jit_data when a subprogram fails to JIT, fixing a memory leak.
> diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
> index b60877478b45d..d9fdb32b7a96c 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 bpf_jit_data *jit_data = fp->aux->jit_data;
[Severity: Low]
Does this code cause a build failure on s390?
It appears struct bpf_jit_data is undefined in this context, as the s390
architecture uses struct s390_jit_data instead.
This leads to a compiler error when trying to dereference it to access
jit_data->ctx.addrs below.
> + 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);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=2
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 3/7] parisc: Fix memory leak in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 3/7] parisc: " Pu Lehui
@ 2026-07-25 10:28 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:28 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The patch introduces a build failure due to the use of an incomplete type (`struct bpf_jit_data`) and an undeclared static inline function (`bpf_jit_binary_hdr`).
--
--- Patch [3]: [PATCH bpf-next v2 3/7] parisc: Fix memory leak in bpf_jit_free ---
commit 8b0b5655843da846b247fa021046070e5875f56c
Author: Pu Lehui <pulehui@huawei.com>
parisc: Fix memory leak in bpf_jit_free
This commit implements a custom bpf_jit_free() for the parisc architecture
to free leftover JIT data when a subprogram fails to JIT.
> diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c
> index 172770132440d..11e13ad6bc509 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 bpf_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);
[Severity: Low]
Will this cause a build failure on parisc?
It looks like struct bpf_jit_data is an incomplete type not defined anywhere
in the kernel, and the correct type used elsewhere in this file is struct
hppa_jit_data.
Additionally, is it possible to call bpf_jit_binary_hdr() here? It appears
to be a static inline function local to kernel/bpf/core.c and is not exported.
> + kfree(jit_data);
> + }
> +
> + bpf_jit_binary_free(hdr);
> + WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
> + }
> +
> + bpf_prog_unlock_free(fp);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 4/7] bpf, sparc64: Fix memory leak in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 4/7] bpf, sparc64: " Pu Lehui
@ 2026-07-25 10:29 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:29 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The patch introduces fatal compilation errors by dereferencing an undefined struct `struct bpf_jit_data` and calling an undeclared function `bpf_jit_binary_hdr`.
--
--- Patch [4]: [PATCH bpf-next v2 4/7] bpf, sparc64: Fix memory leak in bpf_jit_free ---
commit 85bc88f184eccb691d35e9449a95fcc1e9059dca
Author: Pu Lehui <pulehui@huawei.com>
bpf, sparc64: Fix memory leak in bpf_jit_free
If a subprogram fails to JIT in jit_subprogs(), previously JITed
subprograms are freed. However, the generic bpf_jit_free() fails to
free their leftover jit_data, causing a memory leak.
> diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
> index 2fa0e93751276..3b72ff2dba9ce 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 bpf_jit_data *jit_data = fp->aux->jit_data;
> + struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
[Severity: Low]
Does this code introduce a build regression for sparc64? The
architecture-specific struct appears to be struct sparc64_jit_data rather
than struct bpf_jit_data, which would cause an incomplete type error when
dereferencing jit_data->ctx.offset below.
Also, is bpf_jit_binary_hdr() available in this context? It appears to be a
static inline function defined locally in kernel/bpf/core.c, which would cause
an implicit declaration error during compilation here in
arch/sparc/net/bpf_jit_comp_64.c.
> +
> + /* 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);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=4
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 5/7] ARC, bpf: Fix memory leak in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 5/7] ARC, bpf: " Pu Lehui
@ 2026-07-25 10:29 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:29 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Compilation failure due to missing semicolon and undefined struct type in `bpf_jit_free`.
--
--- Patch [5]: [PATCH bpf-next v2 5/7] ARC, bpf: Fix memory leak in bpf_jit_free ---
commit 40d714ef82bd5c9cd5f5fc752d7d4c925d1f6fe9
Author: Pu Lehui <pulehui@huawei.com>
ARC, bpf: Fix memory leak in bpf_jit_free
This patch implements a custom bpf_jit_free() for the ARC architecture.
It cleans up leftover jit_data when a subprogram fails to JIT, addressing
a memory leak that the generic bpf_jit_free() missed.
> diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c
> index 639a2736f029e..45a700f42cd4b 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 bpf_jit_data *jit_data = fp->aux->jit_data;
[Severity: Low]
Does this code cause a build failure? It appears that struct bpf_jit_data
is an undefined type in this context, and ARC uses struct arc_jit_data
for this purpose instead.
> + 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)
[Severity: Low]
Is there a missing semicolon at the end of this kfree() statement?
> + kfree(jit_data);
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=5
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free
2026-07-25 10:20 ` [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
@ 2026-07-25 10:31 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-25 10:31 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] If `bpf_jit_binary_pack_finalize()` fails during `bpf_jit_free()`, it leads to a Use-After-Free and Double-Free of `ro_header`.
- [Medium] Pre-existing memory leaks of intermediate JIT state (`jit_data`, `ctx.offset`, etc.) in other architectures when JIT compilation of subprograms aborts.
- [Medium] The per-CPU private stack (`priv_stack_ptr`) is permanently leaked when JIT compilation fails after allocating `ro_header` on ARM64.
--
--- Patch [1]: [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free ---
commit da1c3e7675f67e35f9b079e317bc882f8ea47e77
Author: Pu Lehui <pulehui@huawei.com>
bpf, arm64: Fix memory leak in bpf_jit_free
When bpf_int_jit_compile() is called for subprograms, it returns early
during the first pass (!prog->is_func || extra_pass is false), keeping
ctx->offset alive for the subsequent extra pass.
If JIT compilation fails for a later subprogram, the BPF core aborts and
calls bpf_jit_free() to clean up the first subprogram. However,
bpf_jit_free() fails to free jit_data->ctx.offset, which causes a memory
leak of the JIT context offsets array.
Fix this by adding the missing kvfree(jit_data->ctx.offset) in
bpf_jit_free().
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index 4cdc7dfb05ba9..f4e4d4578e38a 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -3237,6 +3237,7 @@ void bpf_jit_free(struct bpf_prog *prog)
> */
> if (jit_data) {
> bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
[Severity: High]
This isn't a bug introduced by this patch, but does ignoring the return
value of bpf_jit_binary_pack_finalize() here cause a use-after-free?
If bpf_jit_binary_pack_finalize() fails internally, it frees ro_header.
However, because the return value is ignored, execution continues to:
hdr = bpf_jit_binary_pack_hdr(prog);
bpf_jit_binary_pack_free(hdr, NULL);
This would retrieve the already-freed ro_header and call
bpf_jit_binary_pack_free() on it again, leading to a double-free. Is
it necessary to check the return value of bpf_jit_binary_pack_finalize()
here?
> + kvfree(jit_data->ctx.offset);
[Severity: Medium]
This is a pre-existing issue, but does this same intermediate JIT state
leak in other architectures when JIT compilation of subprograms aborts?
For example, architectures like S390 and SPARC64 allocate jit_data in
bpf_int_jit_compile() but appear to lack a bpf_jit_free() override to
clean it up, falling back to the weak generic implementation which only
frees the binary header.
Additionally, LoongArch's bpf_jit_free() frees jit_data but seems to miss
the same kvfree(jit_data->ctx.offset) that this patch adds for ARM64.
Could these other architectures be updated to prevent permanent memory
leaks of jit_data and ctx.offset on error paths?
[Severity: Medium]
This is also a pre-existing issue, but does the error handling in
bpf_int_jit_compile() permanently leak the private stack?
If bpf_int_jit_compile() fails after allocating ro_header, it jumps to
out_free_hdr:
arch/arm64/net/bpf_jit_comp.c:bpf_int_jit_compile() {
...
out_free_hdr:
if (header) {
bpf_arch_text_copy(&ro_header->size, &header->size,
sizeof(header->size));
bpf_jit_binary_pack_free(ro_header, header);
}
goto out_off;
out_off:
if (!ro_header && priv_stack_ptr) {
free_percpu(priv_stack_ptr);
prog->aux->priv_stack_ptr = NULL;
}
...
}
Because ro_header is freed but never set to NULL before jumping to out_off,
the (!ro_header && priv_stack_ptr) condition evaluates to false, skipping
the free_percpu() call. Since prog->jited is set to 0, bpf_jit_free() also
bypasses its cleanup block, permanently leaking priv_stack_ptr.
Should ro_header be set to NULL in out_free_hdr to ensure the private stack
is properly freed?
> kfree(jit_data);
> }
> prog->bpf_func = (void *)prog->bpf_func - cfi_get_offset();
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260725102020.2287770-1-pulehui@huaweicloud.com?part=1
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-07-25 10:31 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-25 10:20 [PATCH bpf-next v2 0/7] Fixes for bpf_jit_free Pu Lehui
2026-07-25 10:20 ` [PATCH bpf-next v2 1/7] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
2026-07-25 10:31 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 2/7] s390/bpf: " Pu Lehui
2026-07-25 10:27 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 3/7] parisc: " Pu Lehui
2026-07-25 10:28 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 4/7] bpf, sparc64: " Pu Lehui
2026-07-25 10:29 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 5/7] ARC, bpf: " Pu Lehui
2026-07-25 10:29 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 6/7] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
2026-07-25 10:27 ` sashiko-bot
2026-07-25 10:20 ` [PATCH bpf-next v2 7/7] bpf: Fix double-free RO header " Pu Lehui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox