Re: PPC jit and pseudo_btf_id

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

On Tue, Dec 14, 2021 at 2:11 PM Naveen N. Rao
<naveen.n.rao@xxxxxxxxxxxxxxxxxx> wrote:
>
> Hi Yauheni,
>
>
> Yauheni Kaliuta wrote:
> > Hi!
> >
> > I get kernel oops on my setup due to unresolved pseudo_btf_id for
> > ld_imm64 (see 4976b718c355 ("bpf: Introduce pseudo_btf_id")) for
> > example for `test_progs -t for_each/hash_map` where callback
> > address is passed to a bpf helper:
> >
> >
> > [  425.853991] kernel tried to execute user page (100000014) - exploit attempt? (uid: 0)
> > [  425.854173] BUG: Unable to handle kernel instruction fetch
> > [  425.854255] Faulting instruction address: 0x100000014

[...]

>
> Thanks for the problem report. I noticed this recently and have prepared
> a fix as part of a larger patchset.
>

Ah, cool! That was  actually my main question, do I miss the fix somewhere :)

> >
> > The simple patch fixes it for me:
> >
> > diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> > index 90ce75f0f1e2..554c26480387 100644
> > --- a/arch/powerpc/net/bpf_jit_comp.c
> > +++ b/arch/powerpc/net/bpf_jit_comp.c
> > @@ -201,8 +201,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> >                */
> >               bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs);
> >
> > -             /* There is no need to perform the usual passes. */
> > -             goto skip_codegen_passes;
> > +             /* Due to pseudo_btf_id resolving, regenerate */
> >       }
> >
> >       /* Code generation passes 1-2 */
> > @@ -222,7 +221,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> >                               proglen - (cgctx.idx * 4), cgctx.seen);
> >       }
> >
> > -skip_codegen_passes:
> >       if (bpf_jit_enable > 1)
> >               /*
> >                * Note that we output the base address of the code_base
> >
> >
> >
> > Do I miss something?
>
> The problem with the above approach is that we generate variable number
> of instructions for certain BPF instructions and so, unless we reserve
> space for maximum number of powerpc instructions beforehand, we risk
> writing past the end of the allocated buffer.

Yes, agree.

> Can you please check if the below patch fixes the issue for you?

It does, thanks!

I was actually thinking later about something similar and I wonder
about naming. Should the function be renamed to more generic, and is
it really for func_addr only or can be any generic value?

>
>
> Thanks,
> Naveen
>
>
> ---
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 463f99ecaa459e..e16d421ce22a65 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -66,7 +66,15 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
>                          * of the JITed sequence remains unchanged.
>                          */
>                         ctx->idx = tmp_idx;
> +               } else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) {
> +                       func_addr = ((u64)(u32) insn[i].imm) | (((u64)(u32) insn[i+1].imm) << 32);
> +                       tmp_idx = ctx->idx;
> +                       ctx->idx = addrs[i] / 4;
> +                       PPC_LI64(b2p[insn[i].dst_reg], func_addr);
> +                       ctx->idx = tmp_idx;
> +                       i++;
>                 }
> +
>         }
>
>         return 0;
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index 74b465cc7a84d0..4d3973cd78b46f 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -324,6 +324,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
>                 u64 imm64;
>                 u32 true_cond;
>                 u32 tmp_idx;
> +               int j;
>
>                 /*
>                  * addrs[] maps a BPF bytecode address into a real offset from
> @@ -858,7 +859,11 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
>                                     (((u64)(u32) insn[i+1].imm) << 32);
>                         /* Adjust for two bpf instructions */
>                         addrs[++i] = ctx->idx * 4;
> +                       tmp_idx = ctx->idx;
>                         PPC_LI64(dst_reg, imm64);
> +                       /* padding to allow full 5 instructions for later patching */
> +                       for (j = ctx->idx - tmp_idx; j < 5; j++)
> +                               EMIT(PPC_RAW_NOP());
>                         break;
>
>                 /*
>


-- 
WBR, Yauheni




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux