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
