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]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to