@@ -374,6 +374,73 @@ static struct bpf_align_test tests[] = {
374
374
{33 , "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc))" },
375
375
},
376
376
},
377
+ {
378
+ .descr = "packet variable offset 2" ,
379
+ .insns = {
380
+ /* Create an unknown offset, (4n+2)-aligned */
381
+ LOAD_UNKNOWN (BPF_REG_6 ),
382
+ BPF_ALU64_IMM (BPF_LSH , BPF_REG_6 , 2 ),
383
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_6 , 14 ),
384
+ /* Add it to the packet pointer */
385
+ BPF_MOV64_REG (BPF_REG_5 , BPF_REG_2 ),
386
+ BPF_ALU64_REG (BPF_ADD , BPF_REG_5 , BPF_REG_6 ),
387
+ /* Check bounds and perform a read */
388
+ BPF_MOV64_REG (BPF_REG_4 , BPF_REG_5 ),
389
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_4 , 4 ),
390
+ BPF_JMP_REG (BPF_JGE , BPF_REG_3 , BPF_REG_4 , 1 ),
391
+ BPF_EXIT_INSN (),
392
+ BPF_LDX_MEM (BPF_W , BPF_REG_6 , BPF_REG_5 , 0 ),
393
+ /* Make a (4n) offset from the value we just read */
394
+ BPF_ALU64_IMM (BPF_AND , BPF_REG_6 , 0xff ),
395
+ BPF_ALU64_IMM (BPF_LSH , BPF_REG_6 , 2 ),
396
+ /* Add it to the packet pointer */
397
+ BPF_ALU64_REG (BPF_ADD , BPF_REG_5 , BPF_REG_6 ),
398
+ /* Check bounds and perform a read */
399
+ BPF_MOV64_REG (BPF_REG_4 , BPF_REG_5 ),
400
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_4 , 4 ),
401
+ BPF_JMP_REG (BPF_JGE , BPF_REG_3 , BPF_REG_4 , 1 ),
402
+ BPF_EXIT_INSN (),
403
+ BPF_LDX_MEM (BPF_W , BPF_REG_6 , BPF_REG_5 , 0 ),
404
+ BPF_MOV64_IMM (BPF_REG_0 , 0 ),
405
+ BPF_EXIT_INSN (),
406
+ },
407
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
408
+ .matches = {
409
+ /* Calculated offset in R6 has unknown value, but known
410
+ * alignment of 4.
411
+ */
412
+ {8 , "R2=pkt(id=0,off=0,r=8,imm=0)" },
413
+ {8 , "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
414
+ /* Adding 14 makes R6 be (4n+2) */
415
+ {9 , "R6=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))" },
416
+ /* Packet pointer has (4n+2) offset */
417
+ {11 , "R5=pkt(id=1,off=0,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))" },
418
+ {13 , "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))" },
419
+ /* At the time the word size load is performed from R5,
420
+ * its total fixed offset is NET_IP_ALIGN + reg->off (0)
421
+ * which is 2. Then the variable offset is (4n+2), so
422
+ * the total offset is 4-byte aligned and meets the
423
+ * load's requirements.
424
+ */
425
+ {15 , "R5=pkt(id=1,off=0,r=4,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))" },
426
+ /* Newly read value in R6 was shifted left by 2, so has
427
+ * known alignment of 4.
428
+ */
429
+ {18 , "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))" },
430
+ /* Added (4n) to packet pointer's (4n+2) var_off, giving
431
+ * another (4n+2).
432
+ */
433
+ {19 , "R5=pkt(id=2,off=0,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))" },
434
+ {21 , "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))" },
435
+ /* At the time the word size load is performed from R5,
436
+ * its total fixed offset is NET_IP_ALIGN + reg->off (0)
437
+ * which is 2. Then the variable offset is (4n+2), so
438
+ * the total offset is 4-byte aligned and meets the
439
+ * load's requirements.
440
+ */
441
+ {23 , "R5=pkt(id=2,off=0,r=4,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))" },
442
+ },
443
+ },
377
444
};
378
445
379
446
static int probe_filter_length (const struct bpf_insn * fp )
0 commit comments