Re: R? min value is negative, either use unsigned or 'var &= const' #verifier


Yonghong Song
 

On Mon, Mar 11, 2019 at 4:08 AM Simon <contact@...> wrote:

I tried to understand again this verifier error again and probably my previous post does not contain enough information.

I understand that :

93: (67) r0 <<= 32
294: (c7) r0 s>>= 32
295: (b7) r1 = 0
296: (b7) r2 = 0
297: (bf) r3 = r8
298: (79) r4 = *(u64 *)(r10 -40)
299: (bf) r5 = r0
300: (85) call bpf_csum_diff#28
R4 min value is negative, either use unsigned or 'var &= const'

is about this line (in ipv4_l4_csum)

*csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);

R1=0,
R2=0,
R3= R8=pkt(id=0,off=34,r=42,imm=0) = data_start = a pointer to struct udphdr *udp
R4= something in the stack = data_size = __u16 udp_len

So I can not understand how this bring to R4 min value is negative, either use unsigned or 'var &= const'
I took a brief look. Indeed, it is very strange. I can see proper
value of udp_len is stored into
r10 - 40, but when it is retrieved later, the value became unkown....

I will try to experiment with this problem later this week.

Could you do me a favor to make it reproducible with python2? My env.
flexible to rebuild/retry with kernel is python2 friendly.



298: (79) r4 = *(u64 *)(r10 -40)

As I understand this line, r4 will get a value in the stack (R10=fp0,call_-1 fp-48=pkt) and cast this value in a u64, so unsigned. (min value = 0)

(By the way I can not understand why this is a u64 and not a u16 as udp_len variable or u32 as data_size parameter of ipv4_l4_csum function or u32 as tosize from bpf_csum_diff function...)

I tried to use the &= tricks like :

data_size = data_size & 0x1ff;
*csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);

Same issue ...

Here a more longer trace from the verifier :

R0=inv(id=0,umax_value=4295032831,var_off=(0x0; 0x1ffffffff))
R1=inv(id=0,umax_value=65536,var_off=(0x0; 0x1ffff))
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=30,r=42,imm=0)
R10=fp0,call_-1 fp-48=pkt
239: (57) r0 &= 65535
240: (0f) r0 += r1
241: (bf) r1 = r0
242: (77) r1 >>= 16
243: (0f) r1 += r0
244: (a7) r1 ^= -1
245: (6b) *(u16 *)(r7 +24) = r1
246: (b7) r1 = 0
247: (6b) *(u16 *)(r7 +40) = r1
248: (b7) r1 = 0
249: (b7) r2 = 0
250: (79) r3 = *(u64 *)(r10 -48)
251: (b7) r4 = 4
252: (b7) r5 = 0
253: (85) call bpf_csum_diff#28
254: (67) r0 <<= 32
255: (c7) r0 s>>= 32
256: (b7) r1 = 0
257: (b7) r2 = 0
258: (bf) r3 = r9
259: (b7) r4 = 4
260: (bf) r5 = r0
261: (85) call bpf_csum_diff#28
262: (71) r1 = *(u8 *)(r7 +23)
263: (dc) r1 = be32 r1
264: (63) *(u32 *)(r10 -24) = r1
265: (67) r0 <<= 32
266: (c7) r0 s>>= 32
267: (bf) r9 = r10
268: (07) r9 += -24
269: (b7) r1 = 0
270: (b7) r2 = 0
271: (bf) r3 = r9
272: (b7) r4 = 4
273: (bf) r5 = r0
274: (85) call bpf_csum_diff#28
275: (79) r1 = *(u64 *)(r10 -40)
276: (dc) r1 = be32 r1
277: (63) *(u32 *)(r10 -24) = r1
278: (67) r0 <<= 32
279: (c7) r0 s>>= 32
280: (b7) r1 = 0
281: (b7) r2 = 0
282: (bf) r3 = r9
283: (b7) r4 = 4
284: (bf) r5 = r0
285: (85) call bpf_csum_diff#28
286: (67) r0 <<= 32
287: (c7) r0 s>>= 32
288: (b7) r1 = 0
289: (b7) r2 = 0
290: (bf) r3 = r8
291: (79) r4 = *(u64 *)(r10 -40)
292: (bf) r5 = r0
293: (85) call bpf_csum_diff#28

I reference the commit instead of repository to keep the link consistent over the time : https://github.com/sbernard31/udploadbalancer/tree/5ca93d0893a60bc70a75f30eb5cfde496a9e5d93

Again do not hesitate to redirect me to better place if I'm not asking at the right place :)

Thx again for your time.

Join iovisor-dev@lists.iovisor.org to automatically receive all group messages.