Yonghong Song writes:
> On Wed, Mar 6, 2019 at 7:08 AM <[email protected]> wrote: >> >> I'm playing with bcc to prototype an UDP load balancer. >> >> I'm facing an issue that I didn't succeed to understand... >> >> In my code I tried to validate my UDP packet using code like this : >> >> struct udphdr *udp; >> udp = iph + 1; >> if (udp + 1 > data_end) >> return XDP_DROP; >> __u16 udp_len = bpf_ntohs(udp->len); >> //__u16 udp_len = 8; >> if (udp_len < 8) >> return XDP_DROP; >> if (udp_len > 512) // TODO use a more approriate max value >> return XDP_DROP; >> if ((void *) udp + udp_len > data_end) >> return XDP_DROP; >> >> And the verifier does not like it .. > > This is caused by compiler optimizations. > >> >> 28: (71) r2 = *(u8 *)(r7 +23) >> 29: (b7) r0 = 2 >> 30: (55) if r2 != 0x11 goto pc+334 >> R0=inv2 R1=pkt_end(id=0,off=0,imm=0) R2=inv17 R3=inv5 >> R6=ctx(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) >> R8=pkt(id=0,off=34,r=34,imm=0) R9=pkt(id=0,off=14,r=34,imm=0) R10=fp0,call_-1 >> 31: (bf) r2 = r8 >> 32: (07) r2 += 8 >> 33: (b7) r0 = 1 >> 34: (2d) if r2 > r1 goto pc+330 >> R0=inv1 R1=pkt_end(id=0,off=0,imm=0) R2=pkt(id=0,off=42,r=42,imm=0) R3=inv5 >> R6=ctx(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=42,imm=0) >> R8=pkt(id=0,off=34,r=42,imm=0) R9=pkt(id=0,off=14,r=42,imm=0) R10=fp0,call_-1 >> 35: (69) r3 = *(u16 *)(r7 +38) >> 36: (dc) r3 = be16 r3 > > r3 get the value from memory, its value could be any one as permitted > by the type. > >> 37: (bf) r2 = r3 >> 38: (07) r2 += -8 >> 39: (57) r2 &= 65535 >> 40: (b7) r0 = 1 >> 41: (25) if r2 > 0x1f8 goto pc+323 > > test is done by r2. We indeed get better range for r2 (below: > R2=inv(id=0,umax_value=504,var_off=(0x0; 0x1ff)) ) > but r3 range is not tightened. I had run into similar issue when debugging some other rejection before JMP32 introduced when LLVM was generating similar sequences under defult 64-bit mode, but IIRC LLVM generates betweer sequences with -mattr=alu32, under which it will just use w3 (as the type should be optimized into 32-bit) for the comparison. So, I guess this testcase could have easier sequence for verifier under ALU32 mode. But for this case, BPF_END is used which doesn't have sub-register code-gen support inside LLVM for be16 and be32 at the moment (noticed this several days ago when doing some other benchmarking). If I have .i file, I could do a quick prototype to see if ALU32 could improve this. Regards, Jiong -=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#1601): https://lists.iovisor.org/g/iovisor-dev/message/1601 Mute This Topic: https://lists.iovisor.org/mt/30285987/21656 Mute #verifier: https://lists.iovisor.org/mk?hashtag=verifier&subid=2590197 Group Owner: [email protected] Unsubscribe: https://lists.iovisor.org/g/iovisor-dev/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
