From: Daniel Borkmann <daniel@iogearbox.net>
To: Hou Tao <houtao1@huawei.com>, Alexei Starovoitov <ast@kernel.org>
Cc: Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
John Fastabend <john.fastabend@gmail.com>,
Yonghong Song <yhs@fb.com>, Andrii Nakryiko <andrii@kernel.org>,
"David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, KP Singh <kpsingh@kernel.org>,
netdev@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 2/4] bpf: Introduce bpf_int_jit_abort()
Date: Sat, 12 Mar 2022 00:54:12 +0100 [thread overview]
Message-ID: <f4bbf729-b960-de37-8a17-de41bc5559e6@iogearbox.net> (raw)
In-Reply-To: <20220309123321.2400262-3-houtao1@huawei.com>
On 3/9/22 1:33 PM, Hou Tao wrote:
> It will be used to do cleanup for subprog which has been jited in first
> pass but extra pass has not been done. The scenario is possible when
> extra pass for subprog in the middle fails. The failure may lead to
> oops due to inconsistent status for pack allocator (e.g. ro_hdr->size
> and use_bpf_prog_pack) and memory leak in aux->jit_data.
>
> For x86-64, bpf_int_jit_abort() will free allocated memories saved in
> aux->jit_data and fall back to interpreter mode to bypass the calling
> of bpf_jit_binary_pack_free() in bpf_jit_free().
>
> Signed-off-by: Hou Tao <houtao1@huawei.com>
> ---
> arch/x86/net/bpf_jit_comp.c | 24 ++++++++++++++++++++++++
> include/linux/filter.h | 1 +
> kernel/bpf/core.c | 9 +++++++++
> kernel/bpf/verifier.c | 3 +++
> 4 files changed, 37 insertions(+)
>
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index ec3f00be2ac5..49bc0ddd55ae 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -2244,6 +2244,30 @@ struct x64_jit_data {
> struct jit_context ctx;
> };
>
> +void bpf_int_jit_abort(struct bpf_prog *prog)
> +{
> + struct x64_jit_data *jit_data = prog->aux->jit_data;
> + struct bpf_binary_header *header, *rw_header;
> +
> + if (!jit_data)
> + return;
> +
> + prog->bpf_func = NULL;
> + prog->jited = 0;
> + prog->jited_len = 0;
> +
> + header = jit_data->header;
> + rw_header = jit_data->rw_header;
> + bpf_arch_text_copy(&header->size, &rw_header->size,
> + sizeof(rw_header->size));
> + bpf_jit_binary_pack_free(header, rw_header);
> +
> + kvfree(jit_data->addrs);
> + kfree(jit_data);
> +
> + prog->aux->jit_data = NULL;
> +}
> +
> #define MAX_PASSES 20
> #define PADDING_PASSES (MAX_PASSES - 5)
>
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index 9bf26307247f..f3a913229edd 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -945,6 +945,7 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
> (void *)__bpf_call_base)
>
> struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog);
> +void bpf_int_jit_abort(struct bpf_prog *prog);
> void bpf_jit_compile(struct bpf_prog *prog);
> bool bpf_jit_needs_zext(void);
> bool bpf_jit_supports_kfunc_call(void);
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index ab630f773ec1..a1841e11524c 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2636,6 +2636,15 @@ struct bpf_prog * __weak bpf_int_jit_compile(struct bpf_prog *prog)
> return prog;
> }
>
> +/*
> + * If arch JIT uses aux->jit_data to save temporary allocated status and
> + * supports subprog, it needs to override the function to free allocated
> + * memories and fall back to interpreter mode for passed prog.
> + */
> +void __weak bpf_int_jit_abort(struct bpf_prog *prog)
> +{
> +}
> +
> /* Stub for JITs that support eBPF. All cBPF code gets transformed into
> * eBPF by the kernel and is later compiled by bpf_int_jit_compile().
> */
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index e34264200e09..885e515cf83f 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -13086,6 +13086,9 @@ static int jit_subprogs(struct bpf_verifier_env *env)
> if (tmp != func[i] || func[i]->bpf_func != old_bpf_func) {
> verbose(env, "JIT doesn't support bpf-to-bpf calls\n");
> err = -ENOTSUPP;
> + /* Abort extra pass for the remaining subprogs */
> + while (++i < env->subprog_cnt)
> + bpf_int_jit_abort(func[i]);
Don't quite follow this one. For example, if we'd fail in the second pass, the
goto out_addrs from jit would free and clear the prog->aux->jit_data. If we'd succeed
but different prog is returned, prog->aux->jit_data is released and later the goto
out_free in here would clear the jited prog via bpf_jit_free(). Which code path leaves
prog->aux->jit_data as non-NULL such that extra bpf_int_jit_abort() is needed?
> goto out_free;
> }
> cond_resched();
>
next prev parent reply other threads:[~2022-03-11 23:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-09 12:33 [PATCH bpf-next 0/4] fixes for bpf_jit_harden race Hou Tao
2022-03-09 12:33 ` [PATCH bpf-next 1/4] bpf, x86: Fall back to interpreter mode when extra pass fails Hou Tao
2022-03-09 12:33 ` [PATCH bpf-next 2/4] bpf: Introduce bpf_int_jit_abort() Hou Tao
2022-03-11 23:54 ` Daniel Borkmann [this message]
2022-03-12 0:20 ` Daniel Borkmann
2022-03-09 12:33 ` [PATCH bpf-next 3/4] bpf: Fix net.core.bpf_jit_harden race Hou Tao
2022-03-09 23:22 ` Alexei Starovoitov
2022-03-10 1:01 ` Hou Tao
2022-03-10 3:29 ` Alexei Starovoitov
2022-03-10 3:48 ` Hou Tao
2022-03-09 12:33 ` [PATCH bpf-next 4/4] selftests/bpf: Test subprog jit when toggle bpf_jit_harden repeatedly Hou Tao
2022-03-16 22:30 ` [PATCH bpf-next 0/4] fixes for bpf_jit_harden race patchwork-bot+netdevbpf
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=f4bbf729-b960-de37-8a17-de41bc5559e6@iogearbox.net \
--to=daniel@iogearbox.net \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=davem@davemloft.net \
--cc=houtao1@huawei.com \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=yhs@fb.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox