0001
0002 #include <test_progs.h>
0003
0004 #define MAX_INSNS 512
0005 #define MAX_MATCHES 16
0006
0007 struct bpf_reg_match {
0008 unsigned int line;
0009 const char *match;
0010 };
0011
0012 struct bpf_align_test {
0013 const char *descr;
0014 struct bpf_insn insns[MAX_INSNS];
0015 enum {
0016 UNDEF,
0017 ACCEPT,
0018 REJECT
0019 } result;
0020 enum bpf_prog_type prog_type;
0021
0022 struct bpf_reg_match matches[MAX_MATCHES];
0023 };
0024
0025 static struct bpf_align_test tests[] = {
0026
0027
0028
0029 {
0030 .descr = "mov",
0031 .insns = {
0032 BPF_MOV64_IMM(BPF_REG_3, 2),
0033 BPF_MOV64_IMM(BPF_REG_3, 4),
0034 BPF_MOV64_IMM(BPF_REG_3, 8),
0035 BPF_MOV64_IMM(BPF_REG_3, 16),
0036 BPF_MOV64_IMM(BPF_REG_3, 32),
0037 BPF_MOV64_IMM(BPF_REG_0, 0),
0038 BPF_EXIT_INSN(),
0039 },
0040 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0041 .matches = {
0042 {0, "R1=ctx(off=0,imm=0)"},
0043 {0, "R10=fp0"},
0044 {0, "R3_w=2"},
0045 {1, "R3_w=4"},
0046 {2, "R3_w=8"},
0047 {3, "R3_w=16"},
0048 {4, "R3_w=32"},
0049 },
0050 },
0051 {
0052 .descr = "shift",
0053 .insns = {
0054 BPF_MOV64_IMM(BPF_REG_3, 1),
0055 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0056 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0057 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0058 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0059 BPF_ALU64_IMM(BPF_RSH, BPF_REG_3, 4),
0060 BPF_MOV64_IMM(BPF_REG_4, 32),
0061 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0062 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0063 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0064 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0065 BPF_MOV64_IMM(BPF_REG_0, 0),
0066 BPF_EXIT_INSN(),
0067 },
0068 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0069 .matches = {
0070 {0, "R1=ctx(off=0,imm=0)"},
0071 {0, "R10=fp0"},
0072 {0, "R3_w=1"},
0073 {1, "R3_w=2"},
0074 {2, "R3_w=4"},
0075 {3, "R3_w=8"},
0076 {4, "R3_w=16"},
0077 {5, "R3_w=1"},
0078 {6, "R4_w=32"},
0079 {7, "R4_w=16"},
0080 {8, "R4_w=8"},
0081 {9, "R4_w=4"},
0082 {10, "R4_w=2"},
0083 },
0084 },
0085 {
0086 .descr = "addsub",
0087 .insns = {
0088 BPF_MOV64_IMM(BPF_REG_3, 4),
0089 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 4),
0090 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 2),
0091 BPF_MOV64_IMM(BPF_REG_4, 8),
0092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0093 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
0094 BPF_MOV64_IMM(BPF_REG_0, 0),
0095 BPF_EXIT_INSN(),
0096 },
0097 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0098 .matches = {
0099 {0, "R1=ctx(off=0,imm=0)"},
0100 {0, "R10=fp0"},
0101 {0, "R3_w=4"},
0102 {1, "R3_w=8"},
0103 {2, "R3_w=10"},
0104 {3, "R4_w=8"},
0105 {4, "R4_w=12"},
0106 {5, "R4_w=14"},
0107 },
0108 },
0109 {
0110 .descr = "mul",
0111 .insns = {
0112 BPF_MOV64_IMM(BPF_REG_3, 7),
0113 BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 1),
0114 BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 2),
0115 BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 4),
0116 BPF_MOV64_IMM(BPF_REG_0, 0),
0117 BPF_EXIT_INSN(),
0118 },
0119 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0120 .matches = {
0121 {0, "R1=ctx(off=0,imm=0)"},
0122 {0, "R10=fp0"},
0123 {0, "R3_w=7"},
0124 {1, "R3_w=7"},
0125 {2, "R3_w=14"},
0126 {3, "R3_w=56"},
0127 },
0128 },
0129
0130
0131 #define PREP_PKT_POINTERS \
0132 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, \
0133 offsetof(struct __sk_buff, data)), \
0134 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, \
0135 offsetof(struct __sk_buff, data_end))
0136
0137 #define LOAD_UNKNOWN(DST_REG) \
0138 PREP_PKT_POINTERS, \
0139 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), \
0140 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), \
0141 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 1), \
0142 BPF_EXIT_INSN(), \
0143 BPF_LDX_MEM(BPF_B, DST_REG, BPF_REG_2, 0)
0144
0145 {
0146 .descr = "unknown shift",
0147 .insns = {
0148 LOAD_UNKNOWN(BPF_REG_3),
0149 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0150 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0151 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0152 BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
0153 LOAD_UNKNOWN(BPF_REG_4),
0154 BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 5),
0155 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0156 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0157 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0158 BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
0159 BPF_MOV64_IMM(BPF_REG_0, 0),
0160 BPF_EXIT_INSN(),
0161 },
0162 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0163 .matches = {
0164 {6, "R0_w=pkt(off=8,r=8,imm=0)"},
0165 {6, "R3_w=scalar(umax=255,var_off=(0x0; 0xff))"},
0166 {7, "R3_w=scalar(umax=510,var_off=(0x0; 0x1fe))"},
0167 {8, "R3_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0168 {9, "R3_w=scalar(umax=2040,var_off=(0x0; 0x7f8))"},
0169 {10, "R3_w=scalar(umax=4080,var_off=(0x0; 0xff0))"},
0170 {12, "R3_w=pkt_end(off=0,imm=0)"},
0171 {17, "R4_w=scalar(umax=255,var_off=(0x0; 0xff))"},
0172 {18, "R4_w=scalar(umax=8160,var_off=(0x0; 0x1fe0))"},
0173 {19, "R4_w=scalar(umax=4080,var_off=(0x0; 0xff0))"},
0174 {20, "R4_w=scalar(umax=2040,var_off=(0x0; 0x7f8))"},
0175 {21, "R4_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0176 {22, "R4_w=scalar(umax=510,var_off=(0x0; 0x1fe))"},
0177 },
0178 },
0179 {
0180 .descr = "unknown mul",
0181 .insns = {
0182 LOAD_UNKNOWN(BPF_REG_3),
0183 BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
0184 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 1),
0185 BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
0186 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
0187 BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
0188 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 4),
0189 BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
0190 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 8),
0191 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
0192 BPF_MOV64_IMM(BPF_REG_0, 0),
0193 BPF_EXIT_INSN(),
0194 },
0195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0196 .matches = {
0197 {6, "R3_w=scalar(umax=255,var_off=(0x0; 0xff))"},
0198 {7, "R4_w=scalar(id=1,umax=255,var_off=(0x0; 0xff))"},
0199 {8, "R4_w=scalar(umax=255,var_off=(0x0; 0xff))"},
0200 {9, "R4_w=scalar(id=1,umax=255,var_off=(0x0; 0xff))"},
0201 {10, "R4_w=scalar(umax=510,var_off=(0x0; 0x1fe))"},
0202 {11, "R4_w=scalar(id=1,umax=255,var_off=(0x0; 0xff))"},
0203 {12, "R4_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0204 {13, "R4_w=scalar(id=1,umax=255,var_off=(0x0; 0xff))"},
0205 {14, "R4_w=scalar(umax=2040,var_off=(0x0; 0x7f8))"},
0206 {15, "R4_w=scalar(umax=4080,var_off=(0x0; 0xff0))"},
0207 },
0208 },
0209 {
0210 .descr = "packet const offset",
0211 .insns = {
0212 PREP_PKT_POINTERS,
0213 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0214
0215 BPF_MOV64_IMM(BPF_REG_0, 0),
0216
0217
0218 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
0219 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0220 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0221 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0222 BPF_EXIT_INSN(),
0223
0224 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 0),
0225 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 1),
0226 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 2),
0227 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 3),
0228 BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 0),
0229 BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 2),
0230 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
0231
0232 BPF_MOV64_IMM(BPF_REG_0, 0),
0233 BPF_EXIT_INSN(),
0234 },
0235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0236 .matches = {
0237 {2, "R5_w=pkt(off=0,r=0,imm=0)"},
0238 {4, "R5_w=pkt(off=14,r=0,imm=0)"},
0239 {5, "R4_w=pkt(off=14,r=0,imm=0)"},
0240 {9, "R2=pkt(off=0,r=18,imm=0)"},
0241 {10, "R5=pkt(off=14,r=18,imm=0)"},
0242 {10, "R4_w=scalar(umax=255,var_off=(0x0; 0xff))"},
0243 {13, "R4_w=scalar(umax=65535,var_off=(0x0; 0xffff))"},
0244 {14, "R4_w=scalar(umax=65535,var_off=(0x0; 0xffff))"},
0245 },
0246 },
0247 {
0248 .descr = "packet variable offset",
0249 .insns = {
0250 LOAD_UNKNOWN(BPF_REG_6),
0251 BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
0252
0253
0254
0255
0256 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0257 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
0258 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0259 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0260 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0261 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0262 BPF_EXIT_INSN(),
0263 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
0264
0265
0266
0267
0268 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0269 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0270 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
0271 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0272 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0273 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0274 BPF_EXIT_INSN(),
0275 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
0276
0277
0278
0279
0280 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0281 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
0282 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 4),
0284 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0285 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0286 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0287 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0288 BPF_EXIT_INSN(),
0289 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
0290
0291 BPF_MOV64_IMM(BPF_REG_0, 0),
0292 BPF_EXIT_INSN(),
0293 },
0294 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0295 .matches = {
0296
0297
0298
0299 {6, "R2_w=pkt(off=0,r=8,imm=0)"},
0300 {7, "R6_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0301
0302
0303
0304 {11, "R5_w=pkt(id=1,off=14,r=0,umax=1020,var_off=(0x0; 0x3fc))"},
0305
0306
0307
0308
0309
0310
0311 {15, "R4=pkt(id=1,off=18,r=18,umax=1020,var_off=(0x0; 0x3fc))"},
0312 {15, "R5=pkt(id=1,off=14,r=18,umax=1020,var_off=(0x0; 0x3fc))"},
0313
0314
0315
0316 {17, "R5_w=pkt(id=2,off=0,r=0,umax=1020,var_off=(0x0; 0x3fc))"},
0317
0318
0319
0320 {18, "R5_w=pkt(id=2,off=14,r=0,umax=1020,var_off=(0x0; 0x3fc))"},
0321
0322
0323
0324
0325
0326
0327 {23, "R4=pkt(id=2,off=18,r=18,umax=1020,var_off=(0x0; 0x3fc))"},
0328 {23, "R5=pkt(id=2,off=14,r=18,umax=1020,var_off=(0x0; 0x3fc))"},
0329
0330
0331
0332 {25, "R5_w=pkt(off=14,r=8"},
0333
0334
0335
0336 {26, "R5_w=pkt(id=3,off=14,r=0,umax=1020,var_off=(0x0; 0x3fc))"},
0337
0338 {27, "R5_w=pkt(id=3,off=18,r=0,umax=1020,var_off=(0x0; 0x3fc))"},
0339
0340
0341
0342
0343 {28, "R5_w=pkt(id=4,off=18,r=0,umax=2040,var_off=(0x0; 0x7fc)"},
0344
0345
0346
0347
0348
0349
0350 {33, "R4=pkt(id=4,off=22,r=22,umax=2040,var_off=(0x0; 0x7fc)"},
0351 {33, "R5=pkt(id=4,off=18,r=22,umax=2040,var_off=(0x0; 0x7fc)"},
0352 },
0353 },
0354 {
0355 .descr = "packet variable offset 2",
0356 .insns = {
0357
0358 LOAD_UNKNOWN(BPF_REG_6),
0359 BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
0360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 14),
0361
0362 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0363 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0364
0365 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0366 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0367 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0368 BPF_EXIT_INSN(),
0369 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
0370
0371 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 0xff),
0372 BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
0373
0374 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0375
0376 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0378 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0379 BPF_EXIT_INSN(),
0380 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
0381 BPF_MOV64_IMM(BPF_REG_0, 0),
0382 BPF_EXIT_INSN(),
0383 },
0384 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0385 .matches = {
0386
0387
0388
0389 {6, "R2_w=pkt(off=0,r=8,imm=0)"},
0390 {7, "R6_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0391
0392 {8, "R6_w=scalar(umin=14,umax=1034,var_off=(0x2; 0x7fc))"},
0393
0394 {11, "R5_w=pkt(id=1,off=0,r=0,umin=14,umax=1034,var_off=(0x2; 0x7fc)"},
0395 {12, "R4=pkt(id=1,off=4,r=0,umin=14,umax=1034,var_off=(0x2; 0x7fc)"},
0396
0397
0398
0399
0400
0401
0402 {15, "R5=pkt(id=1,off=0,r=4,umin=14,umax=1034,var_off=(0x2; 0x7fc)"},
0403
0404
0405
0406 {17, "R6_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0407
0408
0409
0410 {19, "R5_w=pkt(id=2,off=0,r=0,umin=14,umax=2054,var_off=(0x2; 0xffc)"},
0411 {20, "R4=pkt(id=2,off=4,r=0,umin=14,umax=2054,var_off=(0x2; 0xffc)"},
0412
0413
0414
0415
0416
0417
0418 {23, "R5=pkt(id=2,off=0,r=4,umin=14,umax=2054,var_off=(0x2; 0xffc)"},
0419 },
0420 },
0421 {
0422 .descr = "dubious pointer arithmetic",
0423 .insns = {
0424 PREP_PKT_POINTERS,
0425 BPF_MOV64_IMM(BPF_REG_0, 0),
0426
0427 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
0428 BPF_ALU64_REG(BPF_SUB, BPF_REG_5, BPF_REG_2),
0429 BPF_ALU64_IMM(BPF_LSH, BPF_REG_5, 2),
0430
0431
0432
0433 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
0434
0435 BPF_JMP_IMM(BPF_JSGE, BPF_REG_5, 0, 1),
0436 BPF_EXIT_INSN(),
0437
0438 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
0439 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
0440
0441 BPF_MOV64_REG(BPF_REG_4, BPF_REG_6),
0442 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0443 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0444 BPF_EXIT_INSN(),
0445 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_6, 0),
0446 BPF_EXIT_INSN(),
0447 },
0448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0449 .result = REJECT,
0450 .matches = {
0451 {3, "R5_w=pkt_end(off=0,imm=0)"},
0452
0453 {5, "R5_w=scalar(smax=9223372036854775804,umax=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc)"},
0454
0455
0456
0457 {6, "R5_w=scalar(smin=-9223372036854775806,smax=9223372036854775806,umin=2,umax=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},
0458
0459 {9, "R5=scalar(umin=2,umax=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
0460
0461 {11, "R6_w=pkt(id=1,off=0,r=0,umin=2,umax=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
0462 {12, "R4_w=pkt(id=1,off=4,r=0,umin=2,umax=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
0463
0464
0465
0466
0467
0468
0469
0470 {15, "R6_w=pkt(id=1,off=0,r=0,umin=2,umax=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
0471 }
0472 },
0473 {
0474 .descr = "variable subtraction",
0475 .insns = {
0476
0477 LOAD_UNKNOWN(BPF_REG_6),
0478 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
0479 BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
0480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 14),
0481
0482
0483
0484 BPF_ALU64_IMM(BPF_LSH, BPF_REG_7, 2),
0485 BPF_ALU64_REG(BPF_SUB, BPF_REG_6, BPF_REG_7),
0486
0487 BPF_JMP_IMM(BPF_JSGE, BPF_REG_6, 0, 1),
0488 BPF_EXIT_INSN(),
0489
0490 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0491 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
0492
0493 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0495 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0496 BPF_EXIT_INSN(),
0497 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
0498 BPF_EXIT_INSN(),
0499 },
0500 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0501 .matches = {
0502
0503
0504
0505 {6, "R2_w=pkt(off=0,r=8,imm=0)"},
0506 {8, "R6_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0507
0508 {9, "R6_w=scalar(umin=14,umax=1034,var_off=(0x2; 0x7fc))"},
0509
0510 {10, "R7_w=scalar(umax=1020,var_off=(0x0; 0x3fc))"},
0511
0512 {11, "R6=scalar(smin=-1006,smax=1034,umin=2,umax=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},
0513
0514 {14, "R6=scalar(umin=2,umax=1034,var_off=(0x2; 0x7fc))"},
0515
0516
0517
0518
0519
0520
0521 {20, "R5=pkt(id=2,off=0,r=4,umin=2,umax=1034,var_off=(0x2; 0x7fc)"},
0522
0523 },
0524 },
0525 {
0526 .descr = "pointer variable subtraction",
0527 .insns = {
0528
0529
0530
0531 LOAD_UNKNOWN(BPF_REG_6),
0532 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
0533 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 0xf),
0534 BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
0535 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 14),
0536
0537 BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
0538 BPF_ALU64_REG(BPF_SUB, BPF_REG_5, BPF_REG_6),
0539
0540
0541
0542 BPF_ALU64_IMM(BPF_LSH, BPF_REG_7, 2),
0543 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 76),
0544
0545 BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_7),
0546
0547 BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
0548 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
0549 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
0550 BPF_EXIT_INSN(),
0551 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
0552 BPF_EXIT_INSN(),
0553 },
0554 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0555 .matches = {
0556
0557
0558
0559 {6, "R2_w=pkt(off=0,r=8,imm=0)"},
0560 {9, "R6_w=scalar(umax=60,var_off=(0x0; 0x3c))"},
0561
0562 {10, "R6_w=scalar(umin=14,umax=74,var_off=(0x2; 0x7c))"},
0563
0564 {13, "R5_w=pkt(id=2,off=0,r=8,umin=18446744073709551542,umax=18446744073709551602,var_off=(0xffffffffffffff82; 0x7c)"},
0565
0566 {14, "R7_w=scalar(umin=76,umax=1096,var_off=(0x0; 0x7fc))"},
0567
0568 {16, "R5_w=pkt(id=3,off=0,r=0,umin=2,umax=1082,var_off=(0x2; 0xfffffffc)"},
0569
0570
0571
0572
0573
0574
0575 {20, "R5=pkt(id=3,off=0,r=4,umin=2,umax=1082,var_off=(0x2; 0xfffffffc)"},
0576 },
0577 },
0578 };
0579
0580 static int probe_filter_length(const struct bpf_insn *fp)
0581 {
0582 int len;
0583
0584 for (len = MAX_INSNS - 1; len > 0; --len)
0585 if (fp[len].code != 0 || fp[len].imm != 0)
0586 break;
0587 return len + 1;
0588 }
0589
0590 static char bpf_vlog[32768];
0591
0592 static int do_test_single(struct bpf_align_test *test)
0593 {
0594 struct bpf_insn *prog = test->insns;
0595 int prog_type = test->prog_type;
0596 char bpf_vlog_copy[32768];
0597 LIBBPF_OPTS(bpf_prog_load_opts, opts,
0598 .prog_flags = BPF_F_STRICT_ALIGNMENT,
0599 .log_buf = bpf_vlog,
0600 .log_size = sizeof(bpf_vlog),
0601 .log_level = 2,
0602 );
0603 const char *line_ptr;
0604 int cur_line = -1;
0605 int prog_len, i;
0606 int fd_prog;
0607 int ret;
0608
0609 prog_len = probe_filter_length(prog);
0610 fd_prog = bpf_prog_load(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
0611 prog, prog_len, &opts);
0612 if (fd_prog < 0 && test->result != REJECT) {
0613 printf("Failed to load program.\n");
0614 printf("%s", bpf_vlog);
0615 ret = 1;
0616 } else if (fd_prog >= 0 && test->result == REJECT) {
0617 printf("Unexpected success to load!\n");
0618 printf("%s", bpf_vlog);
0619 ret = 1;
0620 close(fd_prog);
0621 } else {
0622 ret = 0;
0623
0624 strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
0625 line_ptr = strtok(bpf_vlog_copy, "\n");
0626 for (i = 0; i < MAX_MATCHES; i++) {
0627 struct bpf_reg_match m = test->matches[i];
0628 int tmp;
0629
0630 if (!m.match)
0631 break;
0632 while (line_ptr) {
0633 cur_line = -1;
0634 sscanf(line_ptr, "%u: ", &cur_line);
0635 if (cur_line == -1)
0636 sscanf(line_ptr, "from %u to %u: ", &tmp, &cur_line);
0637 if (cur_line == m.line)
0638 break;
0639 line_ptr = strtok(NULL, "\n");
0640 }
0641 if (!line_ptr) {
0642 printf("Failed to find line %u for match: %s\n",
0643 m.line, m.match);
0644 ret = 1;
0645 printf("%s", bpf_vlog);
0646 break;
0647 }
0648
0649
0650
0651
0652
0653
0654 if (!strstr(line_ptr, m.match)) {
0655 cur_line = -1;
0656 line_ptr = strtok(NULL, "\n");
0657 sscanf(line_ptr, "%u: ", &cur_line);
0658 }
0659 if (cur_line != m.line || !line_ptr ||
0660 !strstr(line_ptr, m.match)) {
0661 printf("Failed to find match %u: %s\n",
0662 m.line, m.match);
0663 ret = 1;
0664 printf("%s", bpf_vlog);
0665 break;
0666 }
0667 }
0668 if (fd_prog >= 0)
0669 close(fd_prog);
0670 }
0671 return ret;
0672 }
0673
0674 void test_align(void)
0675 {
0676 unsigned int i;
0677
0678 for (i = 0; i < ARRAY_SIZE(tests); i++) {
0679 struct bpf_align_test *test = &tests[i];
0680
0681 if (!test__start_subtest(test->descr))
0682 continue;
0683
0684 CHECK_FAIL(do_test_single(test));
0685 }
0686 }