> > > In Classic BPF, negative "k" has special meaning for both BPF_ABS
> and BPF_IND.
> > > So we should consider it invalid for both cases.
> > >
> > > That prevents applications from using it the way you describe.
> > > And it will allow us to add BPF library support for Linux-
> compatible special meanings later, without
> > breaking the ABI.
> > >
> >
> > Aren't these invalid offsets already taken care during the syntax
> > check when we validate the BPF program ?
> > in bpf_validate.c +1499:
> >         /* load absolute instructions */
> >         [(BPF_LD | BPF_ABS | BPF_B)] = {
> >                 .mask = {. dreg = ZERO_REG, .sreg = ZERO_REG},
> >                 .off = { .min = 0, .max = 0},
> >                 .imm = { .min = 0, .max = INT32_MAX},
> >                 .eval = eval_ld_mbuf,
> >         },
> >
> > IIUC, as __rte_bpf_validate fails when we cal rte_bpf_load ( in
> > bpf_load.c +113), we can't even interpret the cBPF program.
> 
> Good point, we can probably consider BPF_ABS case covered by this.

Agree.

> 
> For BPF_IND however it does not seem to exclude any values, and even if
> it did
> we don't know what's in the register. Speaking of which, I just noticed
> that
> we're truncating it.
> 
> I suggest the following logic in pseudo-code:
> 
> static void
> emit_ld_mbuf(struct a64_jit_ctx *ctx, uint32_t op, uint8_t tmp1,
> uint8_t tmp2,
>       uint8_t src, int32_t imm)
> {
>       // ...
> 
>       /* r1 = off: for ABS use imm, for IND use src + imm */
>       if (mode == BPF_ABS) {
>               assert imm >= 0, "verified by verifier"
>               emit MOV W1, #<imm>
>       } else {
>               /* add signed imm to the source register */
>               emit(s) X1 = src + #<imm>
>               /* verify dynamically that offset is within the domain of
> __rte_pktmbuf_read */
>               emit(s) jump_to_epilogue if X1 <s 0 || X1 > INT32_MAX
>       }
> 
>       // ...
> }

I don't know if it's the sum of src+imm that determines special meaning, or 
it's the imm itself.
If it's the imm itself, a simple fix would be to update the validator's 
.imm.max values for BPF_IND from UINT32_MAX to INT32_MAX.


Reply via email to