* [PATCH bpf-next 0/4] Fixes for bpf_jit_free
@ 2026-07-22 11:27 Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Pu Lehui @ 2026-07-22 11:27 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, 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]
Pu Lehui (4):
bpf, arm64: Fix memory leak in bpf_jit_free
LoongArch: 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/arm64/net/bpf_jit_comp.c | 3 ++-
arch/loongarch/net/bpf_jit.c | 3 ++-
arch/powerpc/net/bpf_jit_comp.c | 4 +++-
arch/riscv/net/bpf_jit_core.c | 3 ++-
arch/x86/net/bpf_jit_comp.c | 2 +-
kernel/bpf/core.c | 5 ++---
6 files changed, 12 insertions(+), 8 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free
2026-07-22 11:27 [PATCH bpf-next 0/4] Fixes for bpf_jit_free Pu Lehui
@ 2026-07-22 11:27 ` Pu Lehui
2026-07-22 11:38 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 2/4] LoongArch: BPF: " Pu Lehui
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Pu Lehui @ 2026-07-22 11:27 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, 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>
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] 9+ messages in thread
* [PATCH bpf-next 2/4] LoongArch: BPF: Fix memory leak in bpf_jit_free
2026-07-22 11:27 [PATCH bpf-next 0/4] Fixes for bpf_jit_free Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
@ 2026-07-22 11:27 ` Pu Lehui
2026-07-22 11:35 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 4/4] bpf: Fix double-free RO header " Pu Lehui
3 siblings, 1 reply; 9+ messages in thread
From: Pu Lehui @ 2026-07-22 11:27 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, 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: 4ab17e762b34 ("LoongArch: BPF: Use BPF prog pack allocator")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
arch/loongarch/net/bpf_jit.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 2738b4db1165..3d3ed1677d01 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -2361,6 +2361,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);
}
hdr = bpf_jit_binary_pack_hdr(prog);
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
2026-07-22 11:27 [PATCH bpf-next 0/4] Fixes for bpf_jit_free Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 2/4] LoongArch: BPF: " Pu Lehui
@ 2026-07-22 11:27 ` Pu Lehui
2026-07-22 11:38 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 4/4] bpf: Fix double-free RO header " Pu Lehui
3 siblings, 1 reply; 9+ messages in thread
From: Pu Lehui @ 2026-07-22 11:27 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, 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] 9+ messages in thread
* [PATCH bpf-next 4/4] bpf: Fix double-free RO header in bpf_jit_free
2026-07-22 11:27 [PATCH bpf-next 0/4] Fixes for bpf_jit_free Pu Lehui
` (2 preceding siblings ...)
2026-07-22 11:27 ` [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
@ 2026-07-22 11:27 ` Pu Lehui
2026-07-22 11:33 ` sashiko-bot
3 siblings, 1 reply; 9+ messages in thread
From: Pu Lehui @ 2026-07-22 11:27 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, 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.
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.
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 | 2 +-
arch/loongarch/net/bpf_jit.c | 2 +-
arch/powerpc/net/bpf_jit_comp.c | 4 +++-
arch/riscv/net/bpf_jit_core.c | 2 +-
arch/x86/net/bpf_jit_comp.c | 2 +-
kernel/bpf/core.c | 5 ++---
6 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index f4e4d4578e38..e200b0207f7a 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;
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 3d3ed1677d01..c8c8664dccaf 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;
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 7b07b43575f1..0ca14b7d0b0e 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -339,8 +339,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..440d5b965e60 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;
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index de7515ea1bea..d017bb0397b8 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -3988,7 +3988,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 47fe047ad30b..77195911a3b3 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1237,10 +1237,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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 4/4] bpf: Fix double-free RO header in bpf_jit_free
2026-07-22 11:27 ` [PATCH bpf-next 4/4] bpf: Fix double-free RO header " Pu Lehui
@ 2026-07-22 11:33 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-22 11:33 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] When `bpf_jit_binary_pack_finalize` fails, `bpf_jit_binary_pack_free` reads an uninitialized/garbage `size` from `ro_header->size`, leading to a kernel panic in `vfree()` and module memory uncharge counter corruption.
--
--- Patch [4]: [PATCH bpf-next 4/4] bpf: Fix double-free RO header in bpf_jit_free ---
commit 4586888c771a3a31208f8ce31608697cc4147140
Author: Pu Lehui <pulehui@huawei.com>
bpf: Fix double-free RO header in bpf_jit_free
This commit modifies bpf_jit_binary_pack_finalize() to drop the implicit free
of ro_header on failure. Architectures are updated to explicitly call
bpf_jit_binary_pack_free() in their error paths instead.
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index de7515ea1beae..d017bb0397b88 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -3988,7 +3988,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 47fe047ad30b8..77195911a3b37 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1237,10 +1237,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;
> }
[Severity: Critical]
This is a pre-existing issue, but does reading ro_header->size cause a panic
when bpf_arch_text_copy() fails?
If bpf_arch_text_copy() returns an error, the RO memory was not written, so
ro_header->size contains uninitialized garbage or illegal instructions. Because
kvfree(rw_header) is called unconditionally just before this check, the only
header holding the correct allocation size is destroyed before the caller can
properly free the resource.
When the architecture fallback explicitly calls bpf_jit_binary_pack_free()
(or previously when this function called bpf_prog_pack_free directly), it
reads the garbage size from ro_header->size:
kernel/bpf/core.c:bpf_jit_binary_pack_free() {
u32 size = ro_header->size;
bpf_prog_pack_free(ro_header, size);
...
bpf_jit_uncharge_modmem(size);
}
Since this garbage size typically exceeds BPF_PROG_PACK_SIZE, the allocator
falls back to vfree(ro_header). As ro_header is a pointer to the interior of
a vmalloc'd pack, vfree() will trigger a kernel panic. Additionally,
bpf_jit_uncharge_modmem() drastically underflows the module memory tracking
counter.
Could the size be preserved or passed differently to avoid reading from the
uninitialized RO header during the error path?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722112754.1615201-1-pulehui@huaweicloud.com?part=4
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 2/4] LoongArch: BPF: Fix memory leak in bpf_jit_free
2026-07-22 11:27 ` [PATCH bpf-next 2/4] LoongArch: BPF: " Pu Lehui
@ 2026-07-22 11:35 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-22 11:35 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:
- [High] The patch series correctly fixes a memory leak of `prog->aux->jit_data` on JIT subprogram failure in `arm64` and `loongarch`, but misses the identical architectural flaw in `s390`, `parisc`, and `sparc64`.
--
--- Patch [2]: [PATCH bpf-next 2/4] LoongArch: BPF: Fix memory leak in bpf_jit_free ---
commit cacb56acd5af4ef394049dd1560a358cf9a04bae
Author: Pu Lehui <pulehui@huawei.com>
LoongArch: BPF: Fix memory leak in bpf_jit_free
This commit fixes a memory leak in the LoongArch BPF JIT compiler. When
bpf_int_jit_compile() returns early for subprograms, it leaves ctx->offset
allocated, which bpf_jit_free() previously failed to clean up on abort.
> diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
> index 2738b4db11653..3d3ed1677d018 100644
> --- a/arch/loongarch/net/bpf_jit.c
> +++ b/arch/loongarch/net/bpf_jit.c
> @@ -2361,6 +2361,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);
> }
[Severity: High]
This is a pre-existing issue, but while this patch correctly fixes the memory
leak of the JIT context arrays for LoongArch, do we have the exact same leak
occurring in s390, parisc, and sparc64?
Looking at s390, parisc, and sparc64, they also return early for subprograms
and leave memory attached to prog->aux->jit_data. For example, in s390:
arch/s390/net/bpf_jit_comp.c:bpf_int_jit_compile() {
...
} else {
jit_data->header = header;
jit_data->ctx = jit;
jit_data->pass = pass;
}
...
if (!fp->is_func || extra_pass) {
...
kvfree(jit.addrs);
kfree(jit_data);
fp->aux->jit_data = NULL;
}
}
However, these architectures do not have a custom bpf_jit_free() implementation
and rely on the weak generic bpf_jit_free() function instead:
kernel/bpf/core.c:bpf_jit_free() {
if (fp->jited) {
struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
bpf_jit_binary_free(hdr);
WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
}
bpf_prog_unlock_free(fp);
}
The generic bpf_jit_free() does not check or free prog->aux->jit_data. If JIT
compilation fails for a later subprogram, the BPF core aborts and calls
bpf_jit_free() on all previously JITed subprograms.
Does this mean s390, parisc, and sparc64 will still leak their jit_data and
offset arrays on this failure path?
> hdr = bpf_jit_binary_pack_hdr(prog);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722112754.1615201-1-pulehui@huaweicloud.com?part=2
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free
2026-07-22 11:27 ` [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
@ 2026-07-22 11:38 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-22 11:38 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:
- [High] Memory leak of `jit_data->ctx.offset` in `bpf_jit_free()` for the LoongArch architecture.
--
--- Patch [1]: [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free ---
commit 34ee740bc2723be0c26671951b05fa73e1bfc918
Author: Pu Lehui <pulehui@huawei.com>
bpf, arm64: Fix memory leak in bpf_jit_free
This commit fixes a memory leak in the ARM64 BPF JIT compiler. When
bpf_jit_free() cleans up a subprogram after a later subprogram fails JIT
compilation, it now correctly frees the jit_data->ctx.offset array.
> 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);
> + kvfree(jit_data->ctx.offset);
[Severity: High]
This isn't a bug introduced by this patch, but does the same memory leak
exist in the LoongArch BPF JIT compiler?
Looking at arch/loongarch/net/bpf_jit.c in bpf_jit_free():
if (jit_data) {
bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
kfree(jit_data);
}
It appears jit_data->ctx.offset is not freed there before kfree(jit_data)
is called.
Could this lead to a similar resource leak if userspace loads a BPF program
with multiple subprograms that passes verification but fails JIT compilation?
> kfree(jit_data);
> }
> prog->bpf_func = (void *)prog->bpf_func - cfi_get_offset();
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722112754.1615201-1-pulehui@huaweicloud.com?part=1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
2026-07-22 11:27 ` [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
@ 2026-07-22 11:38 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-22 11:38 UTC (permalink / raw)
To: Pu Lehui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Error path in `bpf_jit_free()` ignores the return value of `bpf_jit_binary_pack_finalize()`, leading to a use-after-free and double-free of the `ro_header`.
- [High] The BPF JIT module memory charge is permanently leaked when `bpf_jit_binary_pack_finalize()` fails.
--
--- Patch [3]: [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free ---
commit 2c7946882741f9c426f80073ff738910e58599f5
Author: Pu Lehui <pulehui@huawei.com>
riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
Adjusts the BPF program entry point in bpf_jit_free() by subtracting the CFI
offset. This correctly restores the original JITed allocation address before
freeing it.
> 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: High]
This is a pre-existing issue, but does bpf_jit_free() ignore the return value
of bpf_jit_binary_pack_finalize() and risk a use-after-free and double-free?
When bpf_jit_binary_pack_finalize() fails, it frees the ro_header internally:
kernel/bpf/core.c:bpf_jit_binary_pack_finalize() {
...
if (IS_ERR(ptr)) {
bpf_prog_pack_free(ro_header, ro_header->size);
return PTR_ERR(ptr);
}
...
}
But here in bpf_jit_free(), the error is ignored, and bpf_jit_binary_pack_free()
is called with the same header:
arch/riscv/net/bpf_jit_core.c:bpf_jit_free() {
...
hdr = bpf_jit_binary_pack_hdr(prog);
bpf_jit_binary_pack_free(hdr, NULL);
...
}
kernel/bpf/core.c:bpf_jit_binary_pack_free() {
...
u32 size = ro_header->size;
bpf_prog_pack_free(ro_header, size);
...
}
If finalization fails, could this lead to a use-after-free read of
ro_header->size, followed by a double-free of the ro_header?
[Severity: High]
This is also a pre-existing issue, but does the error path of
bpf_jit_binary_pack_finalize() permanently leak the BPF JIT module memory
charge?
When bpf_jit_binary_pack_finalize() fails and frees ro_header, it does not
uncharge the memory:
kernel/bpf/core.c:bpf_jit_binary_pack_finalize() {
...
if (IS_ERR(ptr)) {
bpf_prog_pack_free(ro_header, ro_header->size);
return PTR_ERR(ptr);
}
...
}
In other places like bpf_int_jit_compile(), a finalization failure results in
the pointers being set to NULL and bypassing bpf_jit_binary_pack_free(), which
would normally uncharge the memory:
arch/riscv/net/bpf_jit_core.c:bpf_int_jit_compile() {
...
if (WARN_ON(bpf_jit_binary_pack_finalize(...))) {
/* ro_header has been freed */
jit_data->ro_header = NULL;
jit_data->header = NULL;
goto out_free_hdr;
}
...
}
Could repeated failures exhaust the JIT memory limit, resulting in a local DoS
by preventing further BPF program loading?
> WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722112754.1615201-1-pulehui@huaweicloud.com?part=3
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-22 11:38 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-22 11:27 [PATCH bpf-next 0/4] Fixes for bpf_jit_free Pu Lehui
2026-07-22 11:27 ` [PATCH bpf-next 1/4] bpf, arm64: Fix memory leak in bpf_jit_free Pu Lehui
2026-07-22 11:38 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 2/4] LoongArch: BPF: " Pu Lehui
2026-07-22 11:35 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 3/4] riscv, bpf: Adjust bpf_func to account for CFI offset " Pu Lehui
2026-07-22 11:38 ` sashiko-bot
2026-07-22 11:27 ` [PATCH bpf-next 4/4] bpf: Fix double-free RO header " Pu Lehui
2026-07-22 11:33 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.