On 12 January 2017 at 10:50, William Tu via iovisor-dev
<[email protected]> wrote:
> Hi,
>
> I observed that for direct packet access, we have to use this data and
> data_end checking pattern:
>
> int xdp_prog1(struct xdp_md *ctx)
> {
>     void *data_end = (void *)(long)ctx->data_end;
>     void *data = (void *)(long)ctx->data;
>     struct ethhdr *eth = data;
>     ...
>     nh_off = sizeof(*eth);
>     if (nh_off + data > data_end)
>         return rc;
> ---
> if writing in another way like
> ---
>     if ((long)nh_off > data_end - data)
>        return rc;
> ---
> then verifier isn't able to record the packet's range (r=0):
> 0: (61) r2 = *(u32 *)(r1 +0)
> 1: (61) r1 = *(u32 *)(r1 +4)
> 2: (bf) r4 = r1
> 3: (1f) r4 -= r2
> 4: (b7) r3 = 14
> 5: (6d) if r3 s> r4 goto pc+54
>  R1=pkt_end R2=pkt(id=0,off=0,r=0) R3=imm14,min_value=14,max_value=14
> R4=inv,min_value=14 R10=fp
> 6: (71) r5 = *(u8 *)(r2 +12)
> invalid access to packet, off=12 size=1, R2(id=0,off=0,r=0)
>
> Is this the expected behavior?

Currently yes, you can extend the verifier to recognise the code
generated by LLVM for your pattern. What might be even better is to
provide a standard header file with a macro for boundary check
purposes which results in the correct code generation so we avoid
requiring to know the exact pattern to use.
_______________________________________________
iovisor-dev mailing list
[email protected]
https://lists.iovisor.org/mailman/listinfo/iovisor-dev

Reply via email to