All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Pu Lehui" <pulehui@huaweicloud.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v6 2/7] riscv, bpf: Fix memory leak in bpf_jit_free
Date: Wed, 08 Jul 2026 06:54:05 +0000	[thread overview]
Message-ID: <20260708065406.66B4A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260708064436.2971933-3-pulehui@huaweicloud.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] bpf_jit_free() ignores the error return value of bpf_jit_binary_pack_finalize(), leading to a Use-After-Free, Double-Free, and potential JIT memory charge limit corruption.
- [High] The identical memory leak fixed in RISC-V remains present in ARM64 and LoongArch BPF JIT implementations.
- [High] Memory charge limit (modmem) is permanently leaked when bpf_jit_binary_pack_finalize() fails in bpf_int_jit_compile().
--

--- Patch [2]: [PATCH bpf-next v6 2/7] riscv, bpf: Fix memory leak in bpf_jit_free ---
commit 9c17e0351f5dcd9f2cb6815fc5c5e2c47b738ba2
Author: Pu Lehui <pulehui@huawei.com>

riscv, bpf: Fix memory leak in bpf_jit_free

This commit fixes a memory leak in the RISC-V BPF JIT compiler. When a
subprogram fails to compile, it cleans up earlier subprograms but previously
failed to free the jit_data->ctx.offset array.

> diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
> --- a/arch/riscv/net/bpf_jit_core.c
> +++ b/arch/riscv/net/bpf_jit_core.c
> @@ -234,6 +234,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: Critical]
This is a pre-existing issue, but does ignoring the return value of
bpf_jit_binary_pack_finalize() here cause a use-after-free and double-free?

If bpf_jit_binary_pack_finalize() fails (for example, due to a text copy
failure), it frees the ro_header memory chunk and returns an error:

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);
    }
    ...
}

Since bpf_jit_free() ignores this failure, it extracts the now-freed
ro_header via bpf_jit_binary_pack_hdr() below, and unconditionally passes
it to bpf_jit_binary_pack_free(). Inside that function, the freed ro_header
is dereferenced to read its size, leading to a use-after-free, double-free,
and uncharging the modmem with garbage data.

Can this be triggered by an unprivileged BPF program load?

[Severity: High]
This is also a pre-existing issue, but does bpf_jit_binary_pack_finalize()
fail to uncharge the modmem limit when it returns an error?

As shown above, bpf_jit_binary_pack_finalize() frees ro_header on failure
but does not call bpf_jit_uncharge_modmem(). In other callers like
bpf_int_jit_compile(), the error handler detects the failure, clears the
header pointers, and skips calling bpf_jit_binary_pack_free() completely:

arch/riscv/net/bpf_jit_core.c:bpf_int_jit_compile() {
    ...
    if (WARN_ON(bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header))) {
        /* ro_header has been freed */
        jit_data->ro_header = NULL;
        jit_data->header = NULL;
        goto out_free_hdr;
    }
    ...
}

Since out_free_hdr skips bpf_jit_binary_pack_free() when header is NULL,
the modmem uncharge is permanently bypassed. Does this leak the
bpf_jit_limit capacity?

> +			kfree(jit_data->ctx.offset);

[Severity: High]
This isn't a bug introduced by this patch, but do arm64 and loongarch have
the exact same memory leak that is being fixed here for riscv?

Looking at bpf_jit_free() in arch/arm64/net/bpf_jit_comp.c:

arch/arm64/net/bpf_jit_comp.c:bpf_jit_free() {
    ...
    if (jit_data) {
        bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
        kfree(jit_data);
    }
    ...
}

And similarly in arch/loongarch/net/bpf_jit.c:

arch/loongarch/net/bpf_jit.c:bpf_jit_free() {
    ...
    if (jit_data) {
        bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header);
        kfree(jit_data);
    }
    ...
}

Neither architecture frees the jit_data->ctx.offset array before freeing
jit_data. Should a similar fix be applied to those architectures?

>  			kfree(jit_data);
>  		}
>  		hdr = bpf_jit_binary_pack_hdr(prog);
>  		bpf_jit_binary_pack_free(hdr, NULL);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260708064436.2971933-1-pulehui@huaweicloud.com?part=2

  reply	other threads:[~2026-07-08  6:54 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08  6:44 [PATCH bpf-next v6 0/7] Mixing bpf2bpf and tailcalls for RV64 Pu Lehui
2026-07-08  6:44 ` Pu Lehui
2026-07-08  6:44 ` [PATCH bpf-next v6 1/7] bpf: Extract the is_struct_ops_tramp helper Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  6:44 ` [PATCH bpf-next v6 2/7] riscv, bpf: Fix memory leak in bpf_jit_free Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  6:54   ` sashiko-bot [this message]
2026-07-08  8:51     ` Pu Lehui
2026-07-09  8:46       ` Daniel Borkmann
2026-07-08  6:44 ` [PATCH bpf-next v6 3/7] riscv, bpf: Using kvzalloc_objs to allocate cache buffer Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  6:44 ` [PATCH bpf-next v6 4/7] riscv, bpf: Fix kernel stack corruption in tailcall with CFI Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  6:44 ` [PATCH bpf-next v6 5/7] riscv, bpf: Add RV_TAILCALL_OFFSET macro to format tailcall offset Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  6:44 ` [PATCH bpf-next v6 6/7] riscv, bpf: Mixing bpf2bpf and tailcalls Pu Lehui
2026-07-08  6:44   ` Pu Lehui
2026-07-08  7:07   ` sashiko-bot
2026-07-08  8:48     ` Pu Lehui
2026-07-08  7:35   ` bot+bpf-ci
2026-07-08  7:35     ` bot+bpf-ci
2026-07-08  8:54     ` Pu Lehui
2026-07-08  8:54       ` Pu Lehui
2026-07-09 11:37       ` Björn Töpel
2026-07-09 11:37         ` Björn Töpel
2026-07-09 15:09         ` Pu Lehui
2026-07-09 15:09           ` Pu Lehui
2026-07-09 19:51           ` Björn Töpel
2026-07-09 19:51             ` Björn Töpel
2026-07-10  0:53             ` Pu Lehui
2026-07-10  0:53               ` Pu Lehui
2026-07-10  9:43               ` Daniel Borkmann
2026-07-10  9:43                 ` Daniel Borkmann
2026-07-08  6:44 ` [PATCH bpf-next v6 7/7] selftests/bpf: Remove tailcalls tests from DENYLIST.riscv64 Pu Lehui
2026-07-08  6:44   ` Pu Lehui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260708065406.66B4A1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=pulehui@huaweicloud.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.