1 /* 2 * Testsuite for eBPF verifier 3 * 4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 */ 10 11 #include <stdio.h> 12 #include <unistd.h> 13 #include <errno.h> 14 #include <string.h> 15 #include <stddef.h> 16 #include <stdbool.h> 17 #include <sched.h> 18 19 #include <sys/resource.h> 20 21 #include <linux/unistd.h> 22 #include <linux/filter.h> 23 #include <linux/bpf_perf_event.h> 24 #include <linux/bpf.h> 25 26 #include "../../../include/linux/filter.h" 27 28 #include "bpf_sys.h" 29 30 #ifndef ARRAY_SIZE 31 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 32 #endif 33 34 #define MAX_INSNS 512 35 #define MAX_FIXUPS 8 36 37 struct bpf_test { 38 const char *descr; 39 struct bpf_insn insns[MAX_INSNS]; 40 int fixup_map1[MAX_FIXUPS]; 41 int fixup_map2[MAX_FIXUPS]; 42 int fixup_prog[MAX_FIXUPS]; 43 const char *errstr; 44 const char *errstr_unpriv; 45 enum { 46 UNDEF, 47 ACCEPT, 48 REJECT 49 } result, result_unpriv; 50 enum bpf_prog_type prog_type; 51 }; 52 53 /* Note we want this to be 64 bit aligned so that the end of our array is 54 * actually the end of the structure. 55 */ 56 #define MAX_ENTRIES 11 57 58 struct test_val { 59 unsigned int index; 60 int foo[MAX_ENTRIES]; 61 }; 62 63 static struct bpf_test tests[] = { 64 { 65 "add+sub+mul", 66 .insns = { 67 BPF_MOV64_IMM(BPF_REG_1, 1), 68 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 2), 69 BPF_MOV64_IMM(BPF_REG_2, 3), 70 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_2), 71 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1), 72 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 3), 73 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 74 BPF_EXIT_INSN(), 75 }, 76 .result = ACCEPT, 77 }, 78 { 79 "unreachable", 80 .insns = { 81 BPF_EXIT_INSN(), 82 BPF_EXIT_INSN(), 83 }, 84 .errstr = "unreachable", 85 .result = REJECT, 86 }, 87 { 88 "unreachable2", 89 .insns = { 90 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 91 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 92 BPF_EXIT_INSN(), 93 }, 94 .errstr = "unreachable", 95 .result = REJECT, 96 }, 97 { 98 "out of range jump", 99 .insns = { 100 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 101 BPF_EXIT_INSN(), 102 }, 103 .errstr = "jump out of range", 104 .result = REJECT, 105 }, 106 { 107 "out of range jump2", 108 .insns = { 109 BPF_JMP_IMM(BPF_JA, 0, 0, -2), 110 BPF_EXIT_INSN(), 111 }, 112 .errstr = "jump out of range", 113 .result = REJECT, 114 }, 115 { 116 "test1 ld_imm64", 117 .insns = { 118 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 119 BPF_LD_IMM64(BPF_REG_0, 0), 120 BPF_LD_IMM64(BPF_REG_0, 0), 121 BPF_LD_IMM64(BPF_REG_0, 1), 122 BPF_LD_IMM64(BPF_REG_0, 1), 123 BPF_MOV64_IMM(BPF_REG_0, 2), 124 BPF_EXIT_INSN(), 125 }, 126 .errstr = "invalid BPF_LD_IMM insn", 127 .errstr_unpriv = "R1 pointer comparison", 128 .result = REJECT, 129 }, 130 { 131 "test2 ld_imm64", 132 .insns = { 133 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 134 BPF_LD_IMM64(BPF_REG_0, 0), 135 BPF_LD_IMM64(BPF_REG_0, 0), 136 BPF_LD_IMM64(BPF_REG_0, 1), 137 BPF_LD_IMM64(BPF_REG_0, 1), 138 BPF_EXIT_INSN(), 139 }, 140 .errstr = "invalid BPF_LD_IMM insn", 141 .errstr_unpriv = "R1 pointer comparison", 142 .result = REJECT, 143 }, 144 { 145 "test3 ld_imm64", 146 .insns = { 147 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 148 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0), 149 BPF_LD_IMM64(BPF_REG_0, 0), 150 BPF_LD_IMM64(BPF_REG_0, 0), 151 BPF_LD_IMM64(BPF_REG_0, 1), 152 BPF_LD_IMM64(BPF_REG_0, 1), 153 BPF_EXIT_INSN(), 154 }, 155 .errstr = "invalid bpf_ld_imm64 insn", 156 .result = REJECT, 157 }, 158 { 159 "test4 ld_imm64", 160 .insns = { 161 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0), 162 BPF_EXIT_INSN(), 163 }, 164 .errstr = "invalid bpf_ld_imm64 insn", 165 .result = REJECT, 166 }, 167 { 168 "test5 ld_imm64", 169 .insns = { 170 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, 0, 0, 0), 171 }, 172 .errstr = "invalid bpf_ld_imm64 insn", 173 .result = REJECT, 174 }, 175 { 176 "no bpf_exit", 177 .insns = { 178 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2), 179 }, 180 .errstr = "jump out of range", 181 .result = REJECT, 182 }, 183 { 184 "loop (back-edge)", 185 .insns = { 186 BPF_JMP_IMM(BPF_JA, 0, 0, -1), 187 BPF_EXIT_INSN(), 188 }, 189 .errstr = "back-edge", 190 .result = REJECT, 191 }, 192 { 193 "loop2 (back-edge)", 194 .insns = { 195 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 196 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 197 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 198 BPF_JMP_IMM(BPF_JA, 0, 0, -4), 199 BPF_EXIT_INSN(), 200 }, 201 .errstr = "back-edge", 202 .result = REJECT, 203 }, 204 { 205 "conditional loop", 206 .insns = { 207 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 208 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 209 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 210 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3), 211 BPF_EXIT_INSN(), 212 }, 213 .errstr = "back-edge", 214 .result = REJECT, 215 }, 216 { 217 "read uninitialized register", 218 .insns = { 219 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 220 BPF_EXIT_INSN(), 221 }, 222 .errstr = "R2 !read_ok", 223 .result = REJECT, 224 }, 225 { 226 "read invalid register", 227 .insns = { 228 BPF_MOV64_REG(BPF_REG_0, -1), 229 BPF_EXIT_INSN(), 230 }, 231 .errstr = "R15 is invalid", 232 .result = REJECT, 233 }, 234 { 235 "program doesn't init R0 before exit", 236 .insns = { 237 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_1), 238 BPF_EXIT_INSN(), 239 }, 240 .errstr = "R0 !read_ok", 241 .result = REJECT, 242 }, 243 { 244 "program doesn't init R0 before exit in all branches", 245 .insns = { 246 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 247 BPF_MOV64_IMM(BPF_REG_0, 1), 248 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2), 249 BPF_EXIT_INSN(), 250 }, 251 .errstr = "R0 !read_ok", 252 .errstr_unpriv = "R1 pointer comparison", 253 .result = REJECT, 254 }, 255 { 256 "stack out of bounds", 257 .insns = { 258 BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0), 259 BPF_EXIT_INSN(), 260 }, 261 .errstr = "invalid stack", 262 .result = REJECT, 263 }, 264 { 265 "invalid call insn1", 266 .insns = { 267 BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, 0, 0, 0, 0), 268 BPF_EXIT_INSN(), 269 }, 270 .errstr = "BPF_CALL uses reserved", 271 .result = REJECT, 272 }, 273 { 274 "invalid call insn2", 275 .insns = { 276 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 1, 0), 277 BPF_EXIT_INSN(), 278 }, 279 .errstr = "BPF_CALL uses reserved", 280 .result = REJECT, 281 }, 282 { 283 "invalid function call", 284 .insns = { 285 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1234567), 286 BPF_EXIT_INSN(), 287 }, 288 .errstr = "invalid func unknown#1234567", 289 .result = REJECT, 290 }, 291 { 292 "uninitialized stack1", 293 .insns = { 294 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 295 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 296 BPF_LD_MAP_FD(BPF_REG_1, 0), 297 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 298 BPF_FUNC_map_lookup_elem), 299 BPF_EXIT_INSN(), 300 }, 301 .fixup_map1 = { 2 }, 302 .errstr = "invalid indirect read from stack", 303 .result = REJECT, 304 }, 305 { 306 "uninitialized stack2", 307 .insns = { 308 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 309 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8), 310 BPF_EXIT_INSN(), 311 }, 312 .errstr = "invalid read from stack", 313 .result = REJECT, 314 }, 315 { 316 "invalid argument register", 317 .insns = { 318 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 319 BPF_FUNC_get_cgroup_classid), 320 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 321 BPF_FUNC_get_cgroup_classid), 322 BPF_EXIT_INSN(), 323 }, 324 .errstr = "R1 !read_ok", 325 .result = REJECT, 326 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 327 }, 328 { 329 "non-invalid argument register", 330 .insns = { 331 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1), 332 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 333 BPF_FUNC_get_cgroup_classid), 334 BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_6), 335 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 336 BPF_FUNC_get_cgroup_classid), 337 BPF_EXIT_INSN(), 338 }, 339 .result = ACCEPT, 340 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 341 }, 342 { 343 "check valid spill/fill", 344 .insns = { 345 /* spill R1(ctx) into stack */ 346 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 347 /* fill it back into R2 */ 348 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8), 349 /* should be able to access R0 = *(R2 + 8) */ 350 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */ 351 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 352 BPF_EXIT_INSN(), 353 }, 354 .errstr_unpriv = "R0 leaks addr", 355 .result = ACCEPT, 356 .result_unpriv = REJECT, 357 }, 358 { 359 "check valid spill/fill, skb mark", 360 .insns = { 361 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1), 362 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8), 363 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 364 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 365 offsetof(struct __sk_buff, mark)), 366 BPF_EXIT_INSN(), 367 }, 368 .result = ACCEPT, 369 .result_unpriv = ACCEPT, 370 }, 371 { 372 "check corrupted spill/fill", 373 .insns = { 374 /* spill R1(ctx) into stack */ 375 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 376 /* mess up with R1 pointer on stack */ 377 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23), 378 /* fill back into R0 should fail */ 379 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 380 BPF_EXIT_INSN(), 381 }, 382 .errstr_unpriv = "attempt to corrupt spilled", 383 .errstr = "corrupted spill", 384 .result = REJECT, 385 }, 386 { 387 "invalid src register in STX", 388 .insns = { 389 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1), 390 BPF_EXIT_INSN(), 391 }, 392 .errstr = "R15 is invalid", 393 .result = REJECT, 394 }, 395 { 396 "invalid dst register in STX", 397 .insns = { 398 BPF_STX_MEM(BPF_B, 14, BPF_REG_10, -1), 399 BPF_EXIT_INSN(), 400 }, 401 .errstr = "R14 is invalid", 402 .result = REJECT, 403 }, 404 { 405 "invalid dst register in ST", 406 .insns = { 407 BPF_ST_MEM(BPF_B, 14, -1, -1), 408 BPF_EXIT_INSN(), 409 }, 410 .errstr = "R14 is invalid", 411 .result = REJECT, 412 }, 413 { 414 "invalid src register in LDX", 415 .insns = { 416 BPF_LDX_MEM(BPF_B, BPF_REG_0, 12, 0), 417 BPF_EXIT_INSN(), 418 }, 419 .errstr = "R12 is invalid", 420 .result = REJECT, 421 }, 422 { 423 "invalid dst register in LDX", 424 .insns = { 425 BPF_LDX_MEM(BPF_B, 11, BPF_REG_1, 0), 426 BPF_EXIT_INSN(), 427 }, 428 .errstr = "R11 is invalid", 429 .result = REJECT, 430 }, 431 { 432 "junk insn", 433 .insns = { 434 BPF_RAW_INSN(0, 0, 0, 0, 0), 435 BPF_EXIT_INSN(), 436 }, 437 .errstr = "invalid BPF_LD_IMM", 438 .result = REJECT, 439 }, 440 { 441 "junk insn2", 442 .insns = { 443 BPF_RAW_INSN(1, 0, 0, 0, 0), 444 BPF_EXIT_INSN(), 445 }, 446 .errstr = "BPF_LDX uses reserved fields", 447 .result = REJECT, 448 }, 449 { 450 "junk insn3", 451 .insns = { 452 BPF_RAW_INSN(-1, 0, 0, 0, 0), 453 BPF_EXIT_INSN(), 454 }, 455 .errstr = "invalid BPF_ALU opcode f0", 456 .result = REJECT, 457 }, 458 { 459 "junk insn4", 460 .insns = { 461 BPF_RAW_INSN(-1, -1, -1, -1, -1), 462 BPF_EXIT_INSN(), 463 }, 464 .errstr = "invalid BPF_ALU opcode f0", 465 .result = REJECT, 466 }, 467 { 468 "junk insn5", 469 .insns = { 470 BPF_RAW_INSN(0x7f, -1, -1, -1, -1), 471 BPF_EXIT_INSN(), 472 }, 473 .errstr = "BPF_ALU uses reserved fields", 474 .result = REJECT, 475 }, 476 { 477 "misaligned read from stack", 478 .insns = { 479 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 480 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -4), 481 BPF_EXIT_INSN(), 482 }, 483 .errstr = "misaligned access", 484 .result = REJECT, 485 }, 486 { 487 "invalid map_fd for function call", 488 .insns = { 489 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 490 BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10), 491 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 492 BPF_LD_MAP_FD(BPF_REG_1, 0), 493 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 494 BPF_FUNC_map_delete_elem), 495 BPF_EXIT_INSN(), 496 }, 497 .errstr = "fd 0 is not pointing to valid bpf_map", 498 .result = REJECT, 499 }, 500 { 501 "don't check return value before access", 502 .insns = { 503 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 504 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 506 BPF_LD_MAP_FD(BPF_REG_1, 0), 507 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 508 BPF_FUNC_map_lookup_elem), 509 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 510 BPF_EXIT_INSN(), 511 }, 512 .fixup_map1 = { 3 }, 513 .errstr = "R0 invalid mem access 'map_value_or_null'", 514 .result = REJECT, 515 }, 516 { 517 "access memory with incorrect alignment", 518 .insns = { 519 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 520 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 522 BPF_LD_MAP_FD(BPF_REG_1, 0), 523 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 524 BPF_FUNC_map_lookup_elem), 525 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 526 BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0), 527 BPF_EXIT_INSN(), 528 }, 529 .fixup_map1 = { 3 }, 530 .errstr = "misaligned access", 531 .result = REJECT, 532 }, 533 { 534 "sometimes access memory with incorrect alignment", 535 .insns = { 536 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 537 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 538 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 539 BPF_LD_MAP_FD(BPF_REG_1, 0), 540 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 541 BPF_FUNC_map_lookup_elem), 542 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 543 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 544 BPF_EXIT_INSN(), 545 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1), 546 BPF_EXIT_INSN(), 547 }, 548 .fixup_map1 = { 3 }, 549 .errstr = "R0 invalid mem access", 550 .errstr_unpriv = "R0 leaks addr", 551 .result = REJECT, 552 }, 553 { 554 "jump test 1", 555 .insns = { 556 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 557 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -8), 558 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 559 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0), 560 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1), 561 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 1), 562 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 1), 563 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 2), 564 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 1), 565 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 3), 566 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1), 567 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 4), 568 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1), 569 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 5), 570 BPF_MOV64_IMM(BPF_REG_0, 0), 571 BPF_EXIT_INSN(), 572 }, 573 .errstr_unpriv = "R1 pointer comparison", 574 .result_unpriv = REJECT, 575 .result = ACCEPT, 576 }, 577 { 578 "jump test 2", 579 .insns = { 580 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 581 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2), 582 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0), 583 BPF_JMP_IMM(BPF_JA, 0, 0, 14), 584 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 2), 585 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0), 586 BPF_JMP_IMM(BPF_JA, 0, 0, 11), 587 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 2), 588 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0), 589 BPF_JMP_IMM(BPF_JA, 0, 0, 8), 590 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2), 591 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0), 592 BPF_JMP_IMM(BPF_JA, 0, 0, 5), 593 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 2), 594 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0), 595 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 596 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 1), 597 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0), 598 BPF_MOV64_IMM(BPF_REG_0, 0), 599 BPF_EXIT_INSN(), 600 }, 601 .errstr_unpriv = "R1 pointer comparison", 602 .result_unpriv = REJECT, 603 .result = ACCEPT, 604 }, 605 { 606 "jump test 3", 607 .insns = { 608 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 609 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 610 BPF_ST_MEM(BPF_DW, BPF_REG_2, -8, 0), 611 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 612 BPF_JMP_IMM(BPF_JA, 0, 0, 19), 613 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 3), 614 BPF_ST_MEM(BPF_DW, BPF_REG_2, -16, 0), 615 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 616 BPF_JMP_IMM(BPF_JA, 0, 0, 15), 617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 2, 3), 618 BPF_ST_MEM(BPF_DW, BPF_REG_2, -32, 0), 619 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32), 620 BPF_JMP_IMM(BPF_JA, 0, 0, 11), 621 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 3), 622 BPF_ST_MEM(BPF_DW, BPF_REG_2, -40, 0), 623 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -40), 624 BPF_JMP_IMM(BPF_JA, 0, 0, 7), 625 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 3), 626 BPF_ST_MEM(BPF_DW, BPF_REG_2, -48, 0), 627 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -48), 628 BPF_JMP_IMM(BPF_JA, 0, 0, 3), 629 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 5, 0), 630 BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0), 631 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56), 632 BPF_LD_MAP_FD(BPF_REG_1, 0), 633 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 634 BPF_FUNC_map_delete_elem), 635 BPF_EXIT_INSN(), 636 }, 637 .fixup_map1 = { 24 }, 638 .errstr_unpriv = "R1 pointer comparison", 639 .result_unpriv = REJECT, 640 .result = ACCEPT, 641 }, 642 { 643 "jump test 4", 644 .insns = { 645 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 646 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 647 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 648 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 649 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 650 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 651 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 652 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 653 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 654 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 655 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 656 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 657 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 658 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 659 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 660 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 661 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 662 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 664 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 665 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 666 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 667 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 669 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 670 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 672 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 673 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 674 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 675 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 676 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 677 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 1), 678 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 2), 679 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 3), 680 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 4), 681 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0), 682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0), 683 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0), 684 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0), 685 BPF_MOV64_IMM(BPF_REG_0, 0), 686 BPF_EXIT_INSN(), 687 }, 688 .errstr_unpriv = "R1 pointer comparison", 689 .result_unpriv = REJECT, 690 .result = ACCEPT, 691 }, 692 { 693 "jump test 5", 694 .insns = { 695 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 696 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), 697 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 698 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), 699 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 700 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), 701 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 702 BPF_MOV64_IMM(BPF_REG_0, 0), 703 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 704 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), 705 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 706 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), 707 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 708 BPF_MOV64_IMM(BPF_REG_0, 0), 709 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 710 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), 711 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 712 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), 713 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 714 BPF_MOV64_IMM(BPF_REG_0, 0), 715 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 716 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), 717 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 718 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), 719 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 720 BPF_MOV64_IMM(BPF_REG_0, 0), 721 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 722 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), 723 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 724 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), 725 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 726 BPF_MOV64_IMM(BPF_REG_0, 0), 727 BPF_EXIT_INSN(), 728 }, 729 .errstr_unpriv = "R1 pointer comparison", 730 .result_unpriv = REJECT, 731 .result = ACCEPT, 732 }, 733 { 734 "access skb fields ok", 735 .insns = { 736 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 737 offsetof(struct __sk_buff, len)), 738 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1), 739 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 740 offsetof(struct __sk_buff, mark)), 741 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1), 742 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 743 offsetof(struct __sk_buff, pkt_type)), 744 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1), 745 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 746 offsetof(struct __sk_buff, queue_mapping)), 747 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0), 748 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 749 offsetof(struct __sk_buff, protocol)), 750 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0), 751 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 752 offsetof(struct __sk_buff, vlan_present)), 753 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0), 754 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 755 offsetof(struct __sk_buff, vlan_tci)), 756 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0), 757 BPF_EXIT_INSN(), 758 }, 759 .result = ACCEPT, 760 }, 761 { 762 "access skb fields bad1", 763 .insns = { 764 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4), 765 BPF_EXIT_INSN(), 766 }, 767 .errstr = "invalid bpf_context access", 768 .result = REJECT, 769 }, 770 { 771 "access skb fields bad2", 772 .insns = { 773 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9), 774 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 775 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 776 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 777 BPF_LD_MAP_FD(BPF_REG_1, 0), 778 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 779 BPF_FUNC_map_lookup_elem), 780 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 781 BPF_EXIT_INSN(), 782 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 783 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 784 offsetof(struct __sk_buff, pkt_type)), 785 BPF_EXIT_INSN(), 786 }, 787 .fixup_map1 = { 4 }, 788 .errstr = "different pointers", 789 .errstr_unpriv = "R1 pointer comparison", 790 .result = REJECT, 791 }, 792 { 793 "access skb fields bad3", 794 .insns = { 795 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), 796 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 797 offsetof(struct __sk_buff, pkt_type)), 798 BPF_EXIT_INSN(), 799 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 800 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 801 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 802 BPF_LD_MAP_FD(BPF_REG_1, 0), 803 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 804 BPF_FUNC_map_lookup_elem), 805 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 806 BPF_EXIT_INSN(), 807 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 808 BPF_JMP_IMM(BPF_JA, 0, 0, -12), 809 }, 810 .fixup_map1 = { 6 }, 811 .errstr = "different pointers", 812 .errstr_unpriv = "R1 pointer comparison", 813 .result = REJECT, 814 }, 815 { 816 "access skb fields bad4", 817 .insns = { 818 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 3), 819 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 820 offsetof(struct __sk_buff, len)), 821 BPF_MOV64_IMM(BPF_REG_0, 0), 822 BPF_EXIT_INSN(), 823 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 824 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 825 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 826 BPF_LD_MAP_FD(BPF_REG_1, 0), 827 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 828 BPF_FUNC_map_lookup_elem), 829 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 830 BPF_EXIT_INSN(), 831 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 832 BPF_JMP_IMM(BPF_JA, 0, 0, -13), 833 }, 834 .fixup_map1 = { 7 }, 835 .errstr = "different pointers", 836 .errstr_unpriv = "R1 pointer comparison", 837 .result = REJECT, 838 }, 839 { 840 "check skb->mark is not writeable by sockets", 841 .insns = { 842 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 843 offsetof(struct __sk_buff, mark)), 844 BPF_EXIT_INSN(), 845 }, 846 .errstr = "invalid bpf_context access", 847 .errstr_unpriv = "R1 leaks addr", 848 .result = REJECT, 849 }, 850 { 851 "check skb->tc_index is not writeable by sockets", 852 .insns = { 853 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 854 offsetof(struct __sk_buff, tc_index)), 855 BPF_EXIT_INSN(), 856 }, 857 .errstr = "invalid bpf_context access", 858 .errstr_unpriv = "R1 leaks addr", 859 .result = REJECT, 860 }, 861 { 862 "check non-u32 access to cb", 863 .insns = { 864 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_1, 865 offsetof(struct __sk_buff, cb[0])), 866 BPF_EXIT_INSN(), 867 }, 868 .errstr = "invalid bpf_context access", 869 .errstr_unpriv = "R1 leaks addr", 870 .result = REJECT, 871 }, 872 { 873 "check out of range skb->cb access", 874 .insns = { 875 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 876 offsetof(struct __sk_buff, cb[0]) + 256), 877 BPF_EXIT_INSN(), 878 }, 879 .errstr = "invalid bpf_context access", 880 .errstr_unpriv = "", 881 .result = REJECT, 882 .prog_type = BPF_PROG_TYPE_SCHED_ACT, 883 }, 884 { 885 "write skb fields from socket prog", 886 .insns = { 887 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 888 offsetof(struct __sk_buff, cb[4])), 889 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1), 890 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 891 offsetof(struct __sk_buff, mark)), 892 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 893 offsetof(struct __sk_buff, tc_index)), 894 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1), 895 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 896 offsetof(struct __sk_buff, cb[0])), 897 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 898 offsetof(struct __sk_buff, cb[2])), 899 BPF_EXIT_INSN(), 900 }, 901 .result = ACCEPT, 902 .errstr_unpriv = "R1 leaks addr", 903 .result_unpriv = REJECT, 904 }, 905 { 906 "write skb fields from tc_cls_act prog", 907 .insns = { 908 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 909 offsetof(struct __sk_buff, cb[0])), 910 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 911 offsetof(struct __sk_buff, mark)), 912 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 913 offsetof(struct __sk_buff, tc_index)), 914 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 915 offsetof(struct __sk_buff, tc_index)), 916 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 917 offsetof(struct __sk_buff, cb[3])), 918 BPF_EXIT_INSN(), 919 }, 920 .errstr_unpriv = "", 921 .result_unpriv = REJECT, 922 .result = ACCEPT, 923 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 924 }, 925 { 926 "PTR_TO_STACK store/load", 927 .insns = { 928 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 929 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 930 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 931 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 932 BPF_EXIT_INSN(), 933 }, 934 .result = ACCEPT, 935 }, 936 { 937 "PTR_TO_STACK store/load - bad alignment on off", 938 .insns = { 939 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 941 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 942 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 943 BPF_EXIT_INSN(), 944 }, 945 .result = REJECT, 946 .errstr = "misaligned access off -6 size 8", 947 }, 948 { 949 "PTR_TO_STACK store/load - bad alignment on reg", 950 .insns = { 951 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 952 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 953 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 954 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 955 BPF_EXIT_INSN(), 956 }, 957 .result = REJECT, 958 .errstr = "misaligned access off -2 size 8", 959 }, 960 { 961 "PTR_TO_STACK store/load - out of bounds low", 962 .insns = { 963 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 964 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000), 965 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 966 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 967 BPF_EXIT_INSN(), 968 }, 969 .result = REJECT, 970 .errstr = "invalid stack off=-79992 size=8", 971 }, 972 { 973 "PTR_TO_STACK store/load - out of bounds high", 974 .insns = { 975 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 976 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 977 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 978 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 979 BPF_EXIT_INSN(), 980 }, 981 .result = REJECT, 982 .errstr = "invalid stack off=0 size=8", 983 }, 984 { 985 "unpriv: return pointer", 986 .insns = { 987 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), 988 BPF_EXIT_INSN(), 989 }, 990 .result = ACCEPT, 991 .result_unpriv = REJECT, 992 .errstr_unpriv = "R0 leaks addr", 993 }, 994 { 995 "unpriv: add const to pointer", 996 .insns = { 997 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 998 BPF_MOV64_IMM(BPF_REG_0, 0), 999 BPF_EXIT_INSN(), 1000 }, 1001 .result = ACCEPT, 1002 .result_unpriv = REJECT, 1003 .errstr_unpriv = "R1 pointer arithmetic", 1004 }, 1005 { 1006 "unpriv: add pointer to pointer", 1007 .insns = { 1008 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_10), 1009 BPF_MOV64_IMM(BPF_REG_0, 0), 1010 BPF_EXIT_INSN(), 1011 }, 1012 .result = ACCEPT, 1013 .result_unpriv = REJECT, 1014 .errstr_unpriv = "R1 pointer arithmetic", 1015 }, 1016 { 1017 "unpriv: neg pointer", 1018 .insns = { 1019 BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), 1020 BPF_MOV64_IMM(BPF_REG_0, 0), 1021 BPF_EXIT_INSN(), 1022 }, 1023 .result = ACCEPT, 1024 .result_unpriv = REJECT, 1025 .errstr_unpriv = "R1 pointer arithmetic", 1026 }, 1027 { 1028 "unpriv: cmp pointer with const", 1029 .insns = { 1030 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 1031 BPF_MOV64_IMM(BPF_REG_0, 0), 1032 BPF_EXIT_INSN(), 1033 }, 1034 .result = ACCEPT, 1035 .result_unpriv = REJECT, 1036 .errstr_unpriv = "R1 pointer comparison", 1037 }, 1038 { 1039 "unpriv: cmp pointer with pointer", 1040 .insns = { 1041 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_10, 0), 1042 BPF_MOV64_IMM(BPF_REG_0, 0), 1043 BPF_EXIT_INSN(), 1044 }, 1045 .result = ACCEPT, 1046 .result_unpriv = REJECT, 1047 .errstr_unpriv = "R10 pointer comparison", 1048 }, 1049 { 1050 "unpriv: check that printk is disallowed", 1051 .insns = { 1052 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1053 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1054 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1055 BPF_MOV64_IMM(BPF_REG_2, 8), 1056 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1), 1057 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1058 BPF_FUNC_trace_printk), 1059 BPF_MOV64_IMM(BPF_REG_0, 0), 1060 BPF_EXIT_INSN(), 1061 }, 1062 .errstr_unpriv = "unknown func 6", 1063 .result_unpriv = REJECT, 1064 .result = ACCEPT, 1065 }, 1066 { 1067 "unpriv: pass pointer to helper function", 1068 .insns = { 1069 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1070 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1071 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1072 BPF_LD_MAP_FD(BPF_REG_1, 0), 1073 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), 1074 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 1075 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1076 BPF_FUNC_map_update_elem), 1077 BPF_MOV64_IMM(BPF_REG_0, 0), 1078 BPF_EXIT_INSN(), 1079 }, 1080 .fixup_map1 = { 3 }, 1081 .errstr_unpriv = "R4 leaks addr", 1082 .result_unpriv = REJECT, 1083 .result = ACCEPT, 1084 }, 1085 { 1086 "unpriv: indirectly pass pointer on stack to helper function", 1087 .insns = { 1088 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8), 1089 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1090 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1091 BPF_LD_MAP_FD(BPF_REG_1, 0), 1092 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1093 BPF_FUNC_map_lookup_elem), 1094 BPF_MOV64_IMM(BPF_REG_0, 0), 1095 BPF_EXIT_INSN(), 1096 }, 1097 .fixup_map1 = { 3 }, 1098 .errstr = "invalid indirect read from stack off -8+0 size 8", 1099 .result = REJECT, 1100 }, 1101 { 1102 "unpriv: mangle pointer on stack 1", 1103 .insns = { 1104 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8), 1105 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0), 1106 BPF_MOV64_IMM(BPF_REG_0, 0), 1107 BPF_EXIT_INSN(), 1108 }, 1109 .errstr_unpriv = "attempt to corrupt spilled", 1110 .result_unpriv = REJECT, 1111 .result = ACCEPT, 1112 }, 1113 { 1114 "unpriv: mangle pointer on stack 2", 1115 .insns = { 1116 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8), 1117 BPF_ST_MEM(BPF_B, BPF_REG_10, -1, 0), 1118 BPF_MOV64_IMM(BPF_REG_0, 0), 1119 BPF_EXIT_INSN(), 1120 }, 1121 .errstr_unpriv = "attempt to corrupt spilled", 1122 .result_unpriv = REJECT, 1123 .result = ACCEPT, 1124 }, 1125 { 1126 "unpriv: read pointer from stack in small chunks", 1127 .insns = { 1128 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_10, -8), 1129 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10, -8), 1130 BPF_MOV64_IMM(BPF_REG_0, 0), 1131 BPF_EXIT_INSN(), 1132 }, 1133 .errstr = "invalid size", 1134 .result = REJECT, 1135 }, 1136 { 1137 "unpriv: write pointer into ctx", 1138 .insns = { 1139 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), 1140 BPF_MOV64_IMM(BPF_REG_0, 0), 1141 BPF_EXIT_INSN(), 1142 }, 1143 .errstr_unpriv = "R1 leaks addr", 1144 .result_unpriv = REJECT, 1145 .errstr = "invalid bpf_context access", 1146 .result = REJECT, 1147 }, 1148 { 1149 "unpriv: spill/fill of ctx", 1150 .insns = { 1151 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1152 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1153 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1154 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1155 BPF_MOV64_IMM(BPF_REG_0, 0), 1156 BPF_EXIT_INSN(), 1157 }, 1158 .result = ACCEPT, 1159 }, 1160 { 1161 "unpriv: spill/fill of ctx 2", 1162 .insns = { 1163 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1165 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1166 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1167 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1168 BPF_FUNC_get_hash_recalc), 1169 BPF_EXIT_INSN(), 1170 }, 1171 .result = ACCEPT, 1172 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1173 }, 1174 { 1175 "unpriv: spill/fill of ctx 3", 1176 .insns = { 1177 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1178 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1179 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1180 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0), 1181 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1182 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1183 BPF_FUNC_get_hash_recalc), 1184 BPF_EXIT_INSN(), 1185 }, 1186 .result = REJECT, 1187 .errstr = "R1 type=fp expected=ctx", 1188 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1189 }, 1190 { 1191 "unpriv: spill/fill of ctx 4", 1192 .insns = { 1193 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1195 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1196 BPF_MOV64_IMM(BPF_REG_0, 1), 1197 BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_10, 1198 BPF_REG_0, -8, 0), 1199 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1200 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1201 BPF_FUNC_get_hash_recalc), 1202 BPF_EXIT_INSN(), 1203 }, 1204 .result = REJECT, 1205 .errstr = "R1 type=inv expected=ctx", 1206 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1207 }, 1208 { 1209 "unpriv: spill/fill of different pointers stx", 1210 .insns = { 1211 BPF_MOV64_IMM(BPF_REG_3, 42), 1212 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1213 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1214 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 1215 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1216 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1217 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0), 1218 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), 1219 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1220 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1221 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 1222 offsetof(struct __sk_buff, mark)), 1223 BPF_MOV64_IMM(BPF_REG_0, 0), 1224 BPF_EXIT_INSN(), 1225 }, 1226 .result = REJECT, 1227 .errstr = "same insn cannot be used with different pointers", 1228 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1229 }, 1230 { 1231 "unpriv: spill/fill of different pointers ldx", 1232 .insns = { 1233 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1235 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 1236 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1237 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1238 -(__s32)offsetof(struct bpf_perf_event_data, 1239 sample_period) - 8), 1240 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_2, 0), 1241 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), 1242 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1243 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 1244 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 1245 offsetof(struct bpf_perf_event_data, 1246 sample_period)), 1247 BPF_MOV64_IMM(BPF_REG_0, 0), 1248 BPF_EXIT_INSN(), 1249 }, 1250 .result = REJECT, 1251 .errstr = "same insn cannot be used with different pointers", 1252 .prog_type = BPF_PROG_TYPE_PERF_EVENT, 1253 }, 1254 { 1255 "unpriv: write pointer into map elem value", 1256 .insns = { 1257 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1258 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1259 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1260 BPF_LD_MAP_FD(BPF_REG_1, 0), 1261 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1262 BPF_FUNC_map_lookup_elem), 1263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 1264 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), 1265 BPF_EXIT_INSN(), 1266 }, 1267 .fixup_map1 = { 3 }, 1268 .errstr_unpriv = "R0 leaks addr", 1269 .result_unpriv = REJECT, 1270 .result = ACCEPT, 1271 }, 1272 { 1273 "unpriv: partial copy of pointer", 1274 .insns = { 1275 BPF_MOV32_REG(BPF_REG_1, BPF_REG_10), 1276 BPF_MOV64_IMM(BPF_REG_0, 0), 1277 BPF_EXIT_INSN(), 1278 }, 1279 .errstr_unpriv = "R10 partial copy", 1280 .result_unpriv = REJECT, 1281 .result = ACCEPT, 1282 }, 1283 { 1284 "unpriv: pass pointer to tail_call", 1285 .insns = { 1286 BPF_MOV64_REG(BPF_REG_3, BPF_REG_1), 1287 BPF_LD_MAP_FD(BPF_REG_2, 0), 1288 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1289 BPF_FUNC_tail_call), 1290 BPF_MOV64_IMM(BPF_REG_0, 0), 1291 BPF_EXIT_INSN(), 1292 }, 1293 .fixup_prog = { 1 }, 1294 .errstr_unpriv = "R3 leaks addr into helper", 1295 .result_unpriv = REJECT, 1296 .result = ACCEPT, 1297 }, 1298 { 1299 "unpriv: cmp map pointer with zero", 1300 .insns = { 1301 BPF_MOV64_IMM(BPF_REG_1, 0), 1302 BPF_LD_MAP_FD(BPF_REG_1, 0), 1303 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 1304 BPF_MOV64_IMM(BPF_REG_0, 0), 1305 BPF_EXIT_INSN(), 1306 }, 1307 .fixup_map1 = { 1 }, 1308 .errstr_unpriv = "R1 pointer comparison", 1309 .result_unpriv = REJECT, 1310 .result = ACCEPT, 1311 }, 1312 { 1313 "unpriv: write into frame pointer", 1314 .insns = { 1315 BPF_MOV64_REG(BPF_REG_10, BPF_REG_1), 1316 BPF_MOV64_IMM(BPF_REG_0, 0), 1317 BPF_EXIT_INSN(), 1318 }, 1319 .errstr = "frame pointer is read only", 1320 .result = REJECT, 1321 }, 1322 { 1323 "unpriv: spill/fill frame pointer", 1324 .insns = { 1325 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1327 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, 0), 1328 BPF_LDX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, 0), 1329 BPF_MOV64_IMM(BPF_REG_0, 0), 1330 BPF_EXIT_INSN(), 1331 }, 1332 .errstr = "frame pointer is read only", 1333 .result = REJECT, 1334 }, 1335 { 1336 "unpriv: cmp of frame pointer", 1337 .insns = { 1338 BPF_JMP_IMM(BPF_JEQ, BPF_REG_10, 0, 0), 1339 BPF_MOV64_IMM(BPF_REG_0, 0), 1340 BPF_EXIT_INSN(), 1341 }, 1342 .errstr_unpriv = "R10 pointer comparison", 1343 .result_unpriv = REJECT, 1344 .result = ACCEPT, 1345 }, 1346 { 1347 "unpriv: cmp of stack pointer", 1348 .insns = { 1349 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1350 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1351 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 0), 1352 BPF_MOV64_IMM(BPF_REG_0, 0), 1353 BPF_EXIT_INSN(), 1354 }, 1355 .errstr_unpriv = "R2 pointer comparison", 1356 .result_unpriv = REJECT, 1357 .result = ACCEPT, 1358 }, 1359 { 1360 "unpriv: obfuscate stack pointer", 1361 .insns = { 1362 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1363 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1365 BPF_MOV64_IMM(BPF_REG_0, 0), 1366 BPF_EXIT_INSN(), 1367 }, 1368 .errstr_unpriv = "R2 pointer arithmetic", 1369 .result_unpriv = REJECT, 1370 .result = ACCEPT, 1371 }, 1372 { 1373 "raw_stack: no skb_load_bytes", 1374 .insns = { 1375 BPF_MOV64_IMM(BPF_REG_2, 4), 1376 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1377 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1378 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1379 BPF_MOV64_IMM(BPF_REG_4, 8), 1380 /* Call to skb_load_bytes() omitted. */ 1381 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1382 BPF_EXIT_INSN(), 1383 }, 1384 .result = REJECT, 1385 .errstr = "invalid read from stack off -8+0 size 8", 1386 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1387 }, 1388 { 1389 "raw_stack: skb_load_bytes, negative len", 1390 .insns = { 1391 BPF_MOV64_IMM(BPF_REG_2, 4), 1392 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1393 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1394 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1395 BPF_MOV64_IMM(BPF_REG_4, -8), 1396 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1397 BPF_FUNC_skb_load_bytes), 1398 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1399 BPF_EXIT_INSN(), 1400 }, 1401 .result = REJECT, 1402 .errstr = "invalid stack type R3", 1403 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1404 }, 1405 { 1406 "raw_stack: skb_load_bytes, negative len 2", 1407 .insns = { 1408 BPF_MOV64_IMM(BPF_REG_2, 4), 1409 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1410 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1411 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1412 BPF_MOV64_IMM(BPF_REG_4, ~0), 1413 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1414 BPF_FUNC_skb_load_bytes), 1415 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1416 BPF_EXIT_INSN(), 1417 }, 1418 .result = REJECT, 1419 .errstr = "invalid stack type R3", 1420 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1421 }, 1422 { 1423 "raw_stack: skb_load_bytes, zero len", 1424 .insns = { 1425 BPF_MOV64_IMM(BPF_REG_2, 4), 1426 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1427 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1428 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1429 BPF_MOV64_IMM(BPF_REG_4, 0), 1430 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1431 BPF_FUNC_skb_load_bytes), 1432 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1433 BPF_EXIT_INSN(), 1434 }, 1435 .result = REJECT, 1436 .errstr = "invalid stack type R3", 1437 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1438 }, 1439 { 1440 "raw_stack: skb_load_bytes, no init", 1441 .insns = { 1442 BPF_MOV64_IMM(BPF_REG_2, 4), 1443 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1444 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1445 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1446 BPF_MOV64_IMM(BPF_REG_4, 8), 1447 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1448 BPF_FUNC_skb_load_bytes), 1449 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1450 BPF_EXIT_INSN(), 1451 }, 1452 .result = ACCEPT, 1453 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1454 }, 1455 { 1456 "raw_stack: skb_load_bytes, init", 1457 .insns = { 1458 BPF_MOV64_IMM(BPF_REG_2, 4), 1459 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1461 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xcafe), 1462 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1463 BPF_MOV64_IMM(BPF_REG_4, 8), 1464 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1465 BPF_FUNC_skb_load_bytes), 1466 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1467 BPF_EXIT_INSN(), 1468 }, 1469 .result = ACCEPT, 1470 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1471 }, 1472 { 1473 "raw_stack: skb_load_bytes, spilled regs around bounds", 1474 .insns = { 1475 BPF_MOV64_IMM(BPF_REG_2, 4), 1476 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1477 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16), 1478 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), 1479 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8), 1480 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1481 BPF_MOV64_IMM(BPF_REG_4, 8), 1482 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1483 BPF_FUNC_skb_load_bytes), 1484 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), 1485 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8), 1486 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 1487 offsetof(struct __sk_buff, mark)), 1488 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2, 1489 offsetof(struct __sk_buff, priority)), 1490 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 1491 BPF_EXIT_INSN(), 1492 }, 1493 .result = ACCEPT, 1494 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1495 }, 1496 { 1497 "raw_stack: skb_load_bytes, spilled regs corruption", 1498 .insns = { 1499 BPF_MOV64_IMM(BPF_REG_2, 4), 1500 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1501 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), 1502 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1503 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1504 BPF_MOV64_IMM(BPF_REG_4, 8), 1505 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1506 BPF_FUNC_skb_load_bytes), 1507 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1508 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 1509 offsetof(struct __sk_buff, mark)), 1510 BPF_EXIT_INSN(), 1511 }, 1512 .result = REJECT, 1513 .errstr = "R0 invalid mem access 'inv'", 1514 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1515 }, 1516 { 1517 "raw_stack: skb_load_bytes, spilled regs corruption 2", 1518 .insns = { 1519 BPF_MOV64_IMM(BPF_REG_2, 4), 1520 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16), 1522 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), 1523 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1524 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8), 1525 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1526 BPF_MOV64_IMM(BPF_REG_4, 8), 1527 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1528 BPF_FUNC_skb_load_bytes), 1529 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), 1530 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8), 1531 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0), 1532 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 1533 offsetof(struct __sk_buff, mark)), 1534 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2, 1535 offsetof(struct __sk_buff, priority)), 1536 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 1537 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_3, 1538 offsetof(struct __sk_buff, pkt_type)), 1539 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3), 1540 BPF_EXIT_INSN(), 1541 }, 1542 .result = REJECT, 1543 .errstr = "R3 invalid mem access 'inv'", 1544 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1545 }, 1546 { 1547 "raw_stack: skb_load_bytes, spilled regs + data", 1548 .insns = { 1549 BPF_MOV64_IMM(BPF_REG_2, 4), 1550 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16), 1552 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, -8), 1553 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), 1554 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8), 1555 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1556 BPF_MOV64_IMM(BPF_REG_4, 8), 1557 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1558 BPF_FUNC_skb_load_bytes), 1559 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, -8), 1560 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 8), 1561 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6, 0), 1562 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 1563 offsetof(struct __sk_buff, mark)), 1564 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2, 1565 offsetof(struct __sk_buff, priority)), 1566 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 1567 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3), 1568 BPF_EXIT_INSN(), 1569 }, 1570 .result = ACCEPT, 1571 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1572 }, 1573 { 1574 "raw_stack: skb_load_bytes, invalid access 1", 1575 .insns = { 1576 BPF_MOV64_IMM(BPF_REG_2, 4), 1577 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1578 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -513), 1579 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1580 BPF_MOV64_IMM(BPF_REG_4, 8), 1581 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1582 BPF_FUNC_skb_load_bytes), 1583 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1584 BPF_EXIT_INSN(), 1585 }, 1586 .result = REJECT, 1587 .errstr = "invalid stack type R3 off=-513 access_size=8", 1588 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1589 }, 1590 { 1591 "raw_stack: skb_load_bytes, invalid access 2", 1592 .insns = { 1593 BPF_MOV64_IMM(BPF_REG_2, 4), 1594 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1595 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1), 1596 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1597 BPF_MOV64_IMM(BPF_REG_4, 8), 1598 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1599 BPF_FUNC_skb_load_bytes), 1600 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1601 BPF_EXIT_INSN(), 1602 }, 1603 .result = REJECT, 1604 .errstr = "invalid stack type R3 off=-1 access_size=8", 1605 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1606 }, 1607 { 1608 "raw_stack: skb_load_bytes, invalid access 3", 1609 .insns = { 1610 BPF_MOV64_IMM(BPF_REG_2, 4), 1611 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1612 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 0xffffffff), 1613 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1614 BPF_MOV64_IMM(BPF_REG_4, 0xffffffff), 1615 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1616 BPF_FUNC_skb_load_bytes), 1617 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1618 BPF_EXIT_INSN(), 1619 }, 1620 .result = REJECT, 1621 .errstr = "invalid stack type R3 off=-1 access_size=-1", 1622 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1623 }, 1624 { 1625 "raw_stack: skb_load_bytes, invalid access 4", 1626 .insns = { 1627 BPF_MOV64_IMM(BPF_REG_2, 4), 1628 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1629 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -1), 1630 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1631 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff), 1632 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1633 BPF_FUNC_skb_load_bytes), 1634 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1635 BPF_EXIT_INSN(), 1636 }, 1637 .result = REJECT, 1638 .errstr = "invalid stack type R3 off=-1 access_size=2147483647", 1639 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1640 }, 1641 { 1642 "raw_stack: skb_load_bytes, invalid access 5", 1643 .insns = { 1644 BPF_MOV64_IMM(BPF_REG_2, 4), 1645 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1646 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512), 1647 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1648 BPF_MOV64_IMM(BPF_REG_4, 0x7fffffff), 1649 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1650 BPF_FUNC_skb_load_bytes), 1651 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1652 BPF_EXIT_INSN(), 1653 }, 1654 .result = REJECT, 1655 .errstr = "invalid stack type R3 off=-512 access_size=2147483647", 1656 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1657 }, 1658 { 1659 "raw_stack: skb_load_bytes, invalid access 6", 1660 .insns = { 1661 BPF_MOV64_IMM(BPF_REG_2, 4), 1662 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1663 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512), 1664 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1665 BPF_MOV64_IMM(BPF_REG_4, 0), 1666 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1667 BPF_FUNC_skb_load_bytes), 1668 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1669 BPF_EXIT_INSN(), 1670 }, 1671 .result = REJECT, 1672 .errstr = "invalid stack type R3 off=-512 access_size=0", 1673 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1674 }, 1675 { 1676 "raw_stack: skb_load_bytes, large access", 1677 .insns = { 1678 BPF_MOV64_IMM(BPF_REG_2, 4), 1679 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_10), 1680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -512), 1681 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 1682 BPF_MOV64_IMM(BPF_REG_4, 512), 1683 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1684 BPF_FUNC_skb_load_bytes), 1685 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1686 BPF_EXIT_INSN(), 1687 }, 1688 .result = ACCEPT, 1689 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1690 }, 1691 { 1692 "direct packet access: test1", 1693 .insns = { 1694 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1695 offsetof(struct __sk_buff, data)), 1696 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1697 offsetof(struct __sk_buff, data_end)), 1698 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1700 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 1701 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1702 BPF_MOV64_IMM(BPF_REG_0, 0), 1703 BPF_EXIT_INSN(), 1704 }, 1705 .result = ACCEPT, 1706 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1707 }, 1708 { 1709 "direct packet access: test2", 1710 .insns = { 1711 BPF_MOV64_IMM(BPF_REG_0, 1), 1712 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 1713 offsetof(struct __sk_buff, data_end)), 1714 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1715 offsetof(struct __sk_buff, data)), 1716 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3), 1717 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14), 1718 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15), 1719 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7), 1720 BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12), 1721 BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14), 1722 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1723 offsetof(struct __sk_buff, data)), 1724 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4), 1725 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1), 1726 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 48), 1727 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 48), 1728 BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2), 1729 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3), 1730 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 1731 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 1732 offsetof(struct __sk_buff, data_end)), 1733 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 1734 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4), 1735 BPF_MOV64_IMM(BPF_REG_0, 0), 1736 BPF_EXIT_INSN(), 1737 }, 1738 .result = ACCEPT, 1739 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1740 }, 1741 { 1742 "direct packet access: test3", 1743 .insns = { 1744 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1745 offsetof(struct __sk_buff, data)), 1746 BPF_MOV64_IMM(BPF_REG_0, 0), 1747 BPF_EXIT_INSN(), 1748 }, 1749 .errstr = "invalid bpf_context access off=76", 1750 .result = REJECT, 1751 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 1752 }, 1753 { 1754 "direct packet access: test4 (write)", 1755 .insns = { 1756 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1757 offsetof(struct __sk_buff, data)), 1758 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1759 offsetof(struct __sk_buff, data_end)), 1760 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1761 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1762 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 1763 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 1764 BPF_MOV64_IMM(BPF_REG_0, 0), 1765 BPF_EXIT_INSN(), 1766 }, 1767 .result = ACCEPT, 1768 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1769 }, 1770 { 1771 "direct packet access: test5 (pkt_end >= reg, good access)", 1772 .insns = { 1773 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1774 offsetof(struct __sk_buff, data)), 1775 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1776 offsetof(struct __sk_buff, data_end)), 1777 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1778 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1779 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2), 1780 BPF_MOV64_IMM(BPF_REG_0, 1), 1781 BPF_EXIT_INSN(), 1782 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1783 BPF_MOV64_IMM(BPF_REG_0, 0), 1784 BPF_EXIT_INSN(), 1785 }, 1786 .result = ACCEPT, 1787 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1788 }, 1789 { 1790 "direct packet access: test6 (pkt_end >= reg, bad access)", 1791 .insns = { 1792 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1793 offsetof(struct __sk_buff, data)), 1794 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1795 offsetof(struct __sk_buff, data_end)), 1796 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1797 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1798 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3), 1799 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1800 BPF_MOV64_IMM(BPF_REG_0, 1), 1801 BPF_EXIT_INSN(), 1802 BPF_MOV64_IMM(BPF_REG_0, 0), 1803 BPF_EXIT_INSN(), 1804 }, 1805 .errstr = "invalid access to packet", 1806 .result = REJECT, 1807 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1808 }, 1809 { 1810 "direct packet access: test7 (pkt_end >= reg, both accesses)", 1811 .insns = { 1812 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1813 offsetof(struct __sk_buff, data)), 1814 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1815 offsetof(struct __sk_buff, data_end)), 1816 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1818 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3), 1819 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1820 BPF_MOV64_IMM(BPF_REG_0, 1), 1821 BPF_EXIT_INSN(), 1822 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1823 BPF_MOV64_IMM(BPF_REG_0, 0), 1824 BPF_EXIT_INSN(), 1825 }, 1826 .errstr = "invalid access to packet", 1827 .result = REJECT, 1828 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1829 }, 1830 { 1831 "direct packet access: test8 (double test, variant 1)", 1832 .insns = { 1833 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1834 offsetof(struct __sk_buff, data)), 1835 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1836 offsetof(struct __sk_buff, data_end)), 1837 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1838 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1839 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4), 1840 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 1841 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1842 BPF_MOV64_IMM(BPF_REG_0, 1), 1843 BPF_EXIT_INSN(), 1844 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1845 BPF_MOV64_IMM(BPF_REG_0, 0), 1846 BPF_EXIT_INSN(), 1847 }, 1848 .result = ACCEPT, 1849 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1850 }, 1851 { 1852 "direct packet access: test9 (double test, variant 2)", 1853 .insns = { 1854 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1855 offsetof(struct __sk_buff, data)), 1856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1857 offsetof(struct __sk_buff, data_end)), 1858 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1859 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1860 BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2), 1861 BPF_MOV64_IMM(BPF_REG_0, 1), 1862 BPF_EXIT_INSN(), 1863 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 1864 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1865 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 1866 BPF_MOV64_IMM(BPF_REG_0, 0), 1867 BPF_EXIT_INSN(), 1868 }, 1869 .result = ACCEPT, 1870 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1871 }, 1872 { 1873 "direct packet access: test10 (write invalid)", 1874 .insns = { 1875 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1876 offsetof(struct __sk_buff, data)), 1877 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1878 offsetof(struct __sk_buff, data_end)), 1879 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1880 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1881 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 1882 BPF_MOV64_IMM(BPF_REG_0, 0), 1883 BPF_EXIT_INSN(), 1884 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 1885 BPF_MOV64_IMM(BPF_REG_0, 0), 1886 BPF_EXIT_INSN(), 1887 }, 1888 .errstr = "invalid access to packet", 1889 .result = REJECT, 1890 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1891 }, 1892 { 1893 "helper access to packet: test1, valid packet_ptr range", 1894 .insns = { 1895 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1896 offsetof(struct xdp_md, data)), 1897 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1898 offsetof(struct xdp_md, data_end)), 1899 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 1900 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 1901 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5), 1902 BPF_LD_MAP_FD(BPF_REG_1, 0), 1903 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), 1904 BPF_MOV64_IMM(BPF_REG_4, 0), 1905 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1906 BPF_FUNC_map_update_elem), 1907 BPF_MOV64_IMM(BPF_REG_0, 0), 1908 BPF_EXIT_INSN(), 1909 }, 1910 .fixup_map1 = { 5 }, 1911 .result_unpriv = ACCEPT, 1912 .result = ACCEPT, 1913 .prog_type = BPF_PROG_TYPE_XDP, 1914 }, 1915 { 1916 "helper access to packet: test2, unchecked packet_ptr", 1917 .insns = { 1918 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1919 offsetof(struct xdp_md, data)), 1920 BPF_LD_MAP_FD(BPF_REG_1, 0), 1921 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1922 BPF_FUNC_map_lookup_elem), 1923 BPF_MOV64_IMM(BPF_REG_0, 0), 1924 BPF_EXIT_INSN(), 1925 }, 1926 .fixup_map1 = { 1 }, 1927 .result = REJECT, 1928 .errstr = "invalid access to packet", 1929 .prog_type = BPF_PROG_TYPE_XDP, 1930 }, 1931 { 1932 "helper access to packet: test3, variable add", 1933 .insns = { 1934 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1935 offsetof(struct xdp_md, data)), 1936 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1937 offsetof(struct xdp_md, data_end)), 1938 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 1939 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8), 1940 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10), 1941 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0), 1942 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 1943 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5), 1944 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4), 1945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8), 1946 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4), 1947 BPF_LD_MAP_FD(BPF_REG_1, 0), 1948 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4), 1949 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1950 BPF_FUNC_map_lookup_elem), 1951 BPF_MOV64_IMM(BPF_REG_0, 0), 1952 BPF_EXIT_INSN(), 1953 }, 1954 .fixup_map1 = { 11 }, 1955 .result = ACCEPT, 1956 .prog_type = BPF_PROG_TYPE_XDP, 1957 }, 1958 { 1959 "helper access to packet: test4, packet_ptr with bad range", 1960 .insns = { 1961 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1962 offsetof(struct xdp_md, data)), 1963 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1964 offsetof(struct xdp_md, data_end)), 1965 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 1966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4), 1967 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2), 1968 BPF_MOV64_IMM(BPF_REG_0, 0), 1969 BPF_EXIT_INSN(), 1970 BPF_LD_MAP_FD(BPF_REG_1, 0), 1971 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1972 BPF_FUNC_map_lookup_elem), 1973 BPF_MOV64_IMM(BPF_REG_0, 0), 1974 BPF_EXIT_INSN(), 1975 }, 1976 .fixup_map1 = { 7 }, 1977 .result = REJECT, 1978 .errstr = "invalid access to packet", 1979 .prog_type = BPF_PROG_TYPE_XDP, 1980 }, 1981 { 1982 "helper access to packet: test5, packet_ptr with too short range", 1983 .insns = { 1984 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1985 offsetof(struct xdp_md, data)), 1986 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1987 offsetof(struct xdp_md, data_end)), 1988 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 1989 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 1990 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7), 1991 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3), 1992 BPF_LD_MAP_FD(BPF_REG_1, 0), 1993 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 1994 BPF_FUNC_map_lookup_elem), 1995 BPF_MOV64_IMM(BPF_REG_0, 0), 1996 BPF_EXIT_INSN(), 1997 }, 1998 .fixup_map1 = { 6 }, 1999 .result = REJECT, 2000 .errstr = "invalid access to packet", 2001 .prog_type = BPF_PROG_TYPE_XDP, 2002 }, 2003 { 2004 "helper access to packet: test6, cls valid packet_ptr range", 2005 .insns = { 2006 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2007 offsetof(struct __sk_buff, data)), 2008 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2009 offsetof(struct __sk_buff, data_end)), 2010 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 2011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 2012 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 5), 2013 BPF_LD_MAP_FD(BPF_REG_1, 0), 2014 BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), 2015 BPF_MOV64_IMM(BPF_REG_4, 0), 2016 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2017 BPF_FUNC_map_update_elem), 2018 BPF_MOV64_IMM(BPF_REG_0, 0), 2019 BPF_EXIT_INSN(), 2020 }, 2021 .fixup_map1 = { 5 }, 2022 .result = ACCEPT, 2023 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2024 }, 2025 { 2026 "helper access to packet: test7, cls unchecked packet_ptr", 2027 .insns = { 2028 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2029 offsetof(struct __sk_buff, data)), 2030 BPF_LD_MAP_FD(BPF_REG_1, 0), 2031 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2032 BPF_FUNC_map_lookup_elem), 2033 BPF_MOV64_IMM(BPF_REG_0, 0), 2034 BPF_EXIT_INSN(), 2035 }, 2036 .fixup_map1 = { 1 }, 2037 .result = REJECT, 2038 .errstr = "invalid access to packet", 2039 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2040 }, 2041 { 2042 "helper access to packet: test8, cls variable add", 2043 .insns = { 2044 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2045 offsetof(struct __sk_buff, data)), 2046 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2047 offsetof(struct __sk_buff, data_end)), 2048 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 2049 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8), 2050 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 10), 2051 BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, 0), 2052 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 2053 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_5), 2054 BPF_MOV64_REG(BPF_REG_5, BPF_REG_4), 2055 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 8), 2056 BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_3, 4), 2057 BPF_LD_MAP_FD(BPF_REG_1, 0), 2058 BPF_MOV64_REG(BPF_REG_2, BPF_REG_4), 2059 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2060 BPF_FUNC_map_lookup_elem), 2061 BPF_MOV64_IMM(BPF_REG_0, 0), 2062 BPF_EXIT_INSN(), 2063 }, 2064 .fixup_map1 = { 11 }, 2065 .result = ACCEPT, 2066 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2067 }, 2068 { 2069 "helper access to packet: test9, cls packet_ptr with bad range", 2070 .insns = { 2071 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2072 offsetof(struct __sk_buff, data)), 2073 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2074 offsetof(struct __sk_buff, data_end)), 2075 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 2076 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4), 2077 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 2), 2078 BPF_MOV64_IMM(BPF_REG_0, 0), 2079 BPF_EXIT_INSN(), 2080 BPF_LD_MAP_FD(BPF_REG_1, 0), 2081 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2082 BPF_FUNC_map_lookup_elem), 2083 BPF_MOV64_IMM(BPF_REG_0, 0), 2084 BPF_EXIT_INSN(), 2085 }, 2086 .fixup_map1 = { 7 }, 2087 .result = REJECT, 2088 .errstr = "invalid access to packet", 2089 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2090 }, 2091 { 2092 "helper access to packet: test10, cls packet_ptr with too short range", 2093 .insns = { 2094 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2095 offsetof(struct __sk_buff, data)), 2096 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2097 offsetof(struct __sk_buff, data_end)), 2098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 2099 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2), 2100 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 7), 2101 BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 3), 2102 BPF_LD_MAP_FD(BPF_REG_1, 0), 2103 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2104 BPF_FUNC_map_lookup_elem), 2105 BPF_MOV64_IMM(BPF_REG_0, 0), 2106 BPF_EXIT_INSN(), 2107 }, 2108 .fixup_map1 = { 6 }, 2109 .result = REJECT, 2110 .errstr = "invalid access to packet", 2111 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2112 }, 2113 { 2114 "helper access to packet: test11, cls unsuitable helper 1", 2115 .insns = { 2116 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2117 offsetof(struct __sk_buff, data)), 2118 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2119 offsetof(struct __sk_buff, data_end)), 2120 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2121 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 2122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 7), 2123 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_7, 4), 2124 BPF_MOV64_IMM(BPF_REG_2, 0), 2125 BPF_MOV64_IMM(BPF_REG_4, 42), 2126 BPF_MOV64_IMM(BPF_REG_5, 0), 2127 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2128 BPF_FUNC_skb_store_bytes), 2129 BPF_MOV64_IMM(BPF_REG_0, 0), 2130 BPF_EXIT_INSN(), 2131 }, 2132 .result = REJECT, 2133 .errstr = "helper access to the packet", 2134 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2135 }, 2136 { 2137 "helper access to packet: test12, cls unsuitable helper 2", 2138 .insns = { 2139 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2140 offsetof(struct __sk_buff, data)), 2141 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2142 offsetof(struct __sk_buff, data_end)), 2143 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 2144 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 8), 2145 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 3), 2146 BPF_MOV64_IMM(BPF_REG_2, 0), 2147 BPF_MOV64_IMM(BPF_REG_4, 4), 2148 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2149 BPF_FUNC_skb_load_bytes), 2150 BPF_MOV64_IMM(BPF_REG_0, 0), 2151 BPF_EXIT_INSN(), 2152 }, 2153 .result = REJECT, 2154 .errstr = "helper access to the packet", 2155 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2156 }, 2157 { 2158 "helper access to packet: test13, cls helper ok", 2159 .insns = { 2160 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2161 offsetof(struct __sk_buff, data)), 2162 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2163 offsetof(struct __sk_buff, data_end)), 2164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2165 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2166 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2167 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2168 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2169 BPF_MOV64_IMM(BPF_REG_2, 4), 2170 BPF_MOV64_IMM(BPF_REG_3, 0), 2171 BPF_MOV64_IMM(BPF_REG_4, 0), 2172 BPF_MOV64_IMM(BPF_REG_5, 0), 2173 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2174 BPF_FUNC_csum_diff), 2175 BPF_MOV64_IMM(BPF_REG_0, 0), 2176 BPF_EXIT_INSN(), 2177 }, 2178 .result = ACCEPT, 2179 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2180 }, 2181 { 2182 "helper access to packet: test14, cls helper fail sub", 2183 .insns = { 2184 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2185 offsetof(struct __sk_buff, data)), 2186 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2187 offsetof(struct __sk_buff, data_end)), 2188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2189 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2190 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2191 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2192 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 4), 2193 BPF_MOV64_IMM(BPF_REG_2, 4), 2194 BPF_MOV64_IMM(BPF_REG_3, 0), 2195 BPF_MOV64_IMM(BPF_REG_4, 0), 2196 BPF_MOV64_IMM(BPF_REG_5, 0), 2197 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2198 BPF_FUNC_csum_diff), 2199 BPF_MOV64_IMM(BPF_REG_0, 0), 2200 BPF_EXIT_INSN(), 2201 }, 2202 .result = REJECT, 2203 .errstr = "type=inv expected=fp", 2204 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2205 }, 2206 { 2207 "helper access to packet: test15, cls helper fail range 1", 2208 .insns = { 2209 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2210 offsetof(struct __sk_buff, data)), 2211 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2212 offsetof(struct __sk_buff, data_end)), 2213 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2214 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2216 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2217 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2218 BPF_MOV64_IMM(BPF_REG_2, 8), 2219 BPF_MOV64_IMM(BPF_REG_3, 0), 2220 BPF_MOV64_IMM(BPF_REG_4, 0), 2221 BPF_MOV64_IMM(BPF_REG_5, 0), 2222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2223 BPF_FUNC_csum_diff), 2224 BPF_MOV64_IMM(BPF_REG_0, 0), 2225 BPF_EXIT_INSN(), 2226 }, 2227 .result = REJECT, 2228 .errstr = "invalid access to packet", 2229 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2230 }, 2231 { 2232 "helper access to packet: test16, cls helper fail range 2", 2233 .insns = { 2234 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2235 offsetof(struct __sk_buff, data)), 2236 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2237 offsetof(struct __sk_buff, data_end)), 2238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2239 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2240 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2241 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2242 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2243 BPF_MOV64_IMM(BPF_REG_2, -9), 2244 BPF_MOV64_IMM(BPF_REG_3, 0), 2245 BPF_MOV64_IMM(BPF_REG_4, 0), 2246 BPF_MOV64_IMM(BPF_REG_5, 0), 2247 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2248 BPF_FUNC_csum_diff), 2249 BPF_MOV64_IMM(BPF_REG_0, 0), 2250 BPF_EXIT_INSN(), 2251 }, 2252 .result = REJECT, 2253 .errstr = "invalid access to packet", 2254 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2255 }, 2256 { 2257 "helper access to packet: test17, cls helper fail range 3", 2258 .insns = { 2259 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2260 offsetof(struct __sk_buff, data)), 2261 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2262 offsetof(struct __sk_buff, data_end)), 2263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2265 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2266 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2267 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2268 BPF_MOV64_IMM(BPF_REG_2, ~0), 2269 BPF_MOV64_IMM(BPF_REG_3, 0), 2270 BPF_MOV64_IMM(BPF_REG_4, 0), 2271 BPF_MOV64_IMM(BPF_REG_5, 0), 2272 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2273 BPF_FUNC_csum_diff), 2274 BPF_MOV64_IMM(BPF_REG_0, 0), 2275 BPF_EXIT_INSN(), 2276 }, 2277 .result = REJECT, 2278 .errstr = "invalid access to packet", 2279 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2280 }, 2281 { 2282 "helper access to packet: test18, cls helper fail range zero", 2283 .insns = { 2284 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2285 offsetof(struct __sk_buff, data)), 2286 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2287 offsetof(struct __sk_buff, data_end)), 2288 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2289 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2290 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2291 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2292 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2293 BPF_MOV64_IMM(BPF_REG_2, 0), 2294 BPF_MOV64_IMM(BPF_REG_3, 0), 2295 BPF_MOV64_IMM(BPF_REG_4, 0), 2296 BPF_MOV64_IMM(BPF_REG_5, 0), 2297 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2298 BPF_FUNC_csum_diff), 2299 BPF_MOV64_IMM(BPF_REG_0, 0), 2300 BPF_EXIT_INSN(), 2301 }, 2302 .result = REJECT, 2303 .errstr = "invalid access to packet", 2304 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2305 }, 2306 { 2307 "helper access to packet: test19, pkt end as input", 2308 .insns = { 2309 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2310 offsetof(struct __sk_buff, data)), 2311 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2312 offsetof(struct __sk_buff, data_end)), 2313 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2314 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2315 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2316 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2317 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 2318 BPF_MOV64_IMM(BPF_REG_2, 4), 2319 BPF_MOV64_IMM(BPF_REG_3, 0), 2320 BPF_MOV64_IMM(BPF_REG_4, 0), 2321 BPF_MOV64_IMM(BPF_REG_5, 0), 2322 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2323 BPF_FUNC_csum_diff), 2324 BPF_MOV64_IMM(BPF_REG_0, 0), 2325 BPF_EXIT_INSN(), 2326 }, 2327 .result = REJECT, 2328 .errstr = "R1 type=pkt_end expected=fp", 2329 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2330 }, 2331 { 2332 "helper access to packet: test20, wrong reg", 2333 .insns = { 2334 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 2335 offsetof(struct __sk_buff, data)), 2336 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 2337 offsetof(struct __sk_buff, data_end)), 2338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), 2339 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2340 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), 2341 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_7, 6), 2342 BPF_MOV64_IMM(BPF_REG_2, 4), 2343 BPF_MOV64_IMM(BPF_REG_3, 0), 2344 BPF_MOV64_IMM(BPF_REG_4, 0), 2345 BPF_MOV64_IMM(BPF_REG_5, 0), 2346 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2347 BPF_FUNC_csum_diff), 2348 BPF_MOV64_IMM(BPF_REG_0, 0), 2349 BPF_EXIT_INSN(), 2350 }, 2351 .result = REJECT, 2352 .errstr = "invalid access to packet", 2353 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2354 }, 2355 { 2356 "valid map access into an array with a constant", 2357 .insns = { 2358 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2359 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2361 BPF_LD_MAP_FD(BPF_REG_1, 0), 2362 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2363 BPF_FUNC_map_lookup_elem), 2364 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2365 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2366 offsetof(struct test_val, foo)), 2367 BPF_EXIT_INSN(), 2368 }, 2369 .fixup_map2 = { 3 }, 2370 .errstr_unpriv = "R0 leaks addr", 2371 .result_unpriv = REJECT, 2372 .result = ACCEPT, 2373 }, 2374 { 2375 "valid map access into an array with a register", 2376 .insns = { 2377 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2378 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2379 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2380 BPF_LD_MAP_FD(BPF_REG_1, 0), 2381 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2382 BPF_FUNC_map_lookup_elem), 2383 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), 2384 BPF_MOV64_IMM(BPF_REG_1, 4), 2385 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 2386 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2387 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2388 offsetof(struct test_val, foo)), 2389 BPF_EXIT_INSN(), 2390 }, 2391 .fixup_map2 = { 3 }, 2392 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2393 .result_unpriv = REJECT, 2394 .result = ACCEPT, 2395 }, 2396 { 2397 "valid map access into an array with a variable", 2398 .insns = { 2399 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2400 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2401 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2402 BPF_LD_MAP_FD(BPF_REG_1, 0), 2403 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2404 BPF_FUNC_map_lookup_elem), 2405 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), 2406 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2407 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3), 2408 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 2409 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2410 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2411 offsetof(struct test_val, foo)), 2412 BPF_EXIT_INSN(), 2413 }, 2414 .fixup_map2 = { 3 }, 2415 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2416 .result_unpriv = REJECT, 2417 .result = ACCEPT, 2418 }, 2419 { 2420 "valid map access into an array with a signed variable", 2421 .insns = { 2422 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2423 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2424 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2425 BPF_LD_MAP_FD(BPF_REG_1, 0), 2426 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2427 BPF_FUNC_map_lookup_elem), 2428 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), 2429 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2430 BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1), 2431 BPF_MOV32_IMM(BPF_REG_1, 0), 2432 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES), 2433 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1), 2434 BPF_MOV32_IMM(BPF_REG_1, 0), 2435 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2), 2436 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2437 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2438 offsetof(struct test_val, foo)), 2439 BPF_EXIT_INSN(), 2440 }, 2441 .fixup_map2 = { 3 }, 2442 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2443 .result_unpriv = REJECT, 2444 .result = ACCEPT, 2445 }, 2446 { 2447 "invalid map access into an array with a constant", 2448 .insns = { 2449 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2450 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2451 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2452 BPF_LD_MAP_FD(BPF_REG_1, 0), 2453 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2454 BPF_FUNC_map_lookup_elem), 2455 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2456 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2, 2457 offsetof(struct test_val, foo)), 2458 BPF_EXIT_INSN(), 2459 }, 2460 .fixup_map2 = { 3 }, 2461 .errstr = "invalid access to map value, value_size=48 off=48 size=8", 2462 .result = REJECT, 2463 }, 2464 { 2465 "invalid map access into an array with a register", 2466 .insns = { 2467 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2468 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2469 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2470 BPF_LD_MAP_FD(BPF_REG_1, 0), 2471 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2472 BPF_FUNC_map_lookup_elem), 2473 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), 2474 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1), 2475 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 2476 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2477 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2478 offsetof(struct test_val, foo)), 2479 BPF_EXIT_INSN(), 2480 }, 2481 .fixup_map2 = { 3 }, 2482 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2483 .errstr = "R0 min value is outside of the array range", 2484 .result_unpriv = REJECT, 2485 .result = REJECT, 2486 }, 2487 { 2488 "invalid map access into an array with a variable", 2489 .insns = { 2490 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2491 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2493 BPF_LD_MAP_FD(BPF_REG_1, 0), 2494 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2495 BPF_FUNC_map_lookup_elem), 2496 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), 2497 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2498 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 2499 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2500 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2501 offsetof(struct test_val, foo)), 2502 BPF_EXIT_INSN(), 2503 }, 2504 .fixup_map2 = { 3 }, 2505 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2506 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 2507 .result_unpriv = REJECT, 2508 .result = REJECT, 2509 }, 2510 { 2511 "invalid map access into an array with no floor check", 2512 .insns = { 2513 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2514 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2515 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2516 BPF_LD_MAP_FD(BPF_REG_1, 0), 2517 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2518 BPF_FUNC_map_lookup_elem), 2519 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), 2520 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2521 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES), 2522 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1), 2523 BPF_MOV32_IMM(BPF_REG_1, 0), 2524 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2), 2525 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2526 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2527 offsetof(struct test_val, foo)), 2528 BPF_EXIT_INSN(), 2529 }, 2530 .fixup_map2 = { 3 }, 2531 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2532 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 2533 .result_unpriv = REJECT, 2534 .result = REJECT, 2535 }, 2536 { 2537 "invalid map access into an array with a invalid max check", 2538 .insns = { 2539 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2540 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2541 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2542 BPF_LD_MAP_FD(BPF_REG_1, 0), 2543 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2544 BPF_FUNC_map_lookup_elem), 2545 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), 2546 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2547 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1), 2548 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 2549 BPF_MOV32_IMM(BPF_REG_1, 0), 2550 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2), 2551 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2552 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 2553 offsetof(struct test_val, foo)), 2554 BPF_EXIT_INSN(), 2555 }, 2556 .fixup_map2 = { 3 }, 2557 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2558 .errstr = "invalid access to map value, value_size=48 off=44 size=8", 2559 .result_unpriv = REJECT, 2560 .result = REJECT, 2561 }, 2562 { 2563 "invalid map access into an array with a invalid max check", 2564 .insns = { 2565 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2566 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2567 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2568 BPF_LD_MAP_FD(BPF_REG_1, 0), 2569 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2570 BPF_FUNC_map_lookup_elem), 2571 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10), 2572 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), 2573 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2574 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2575 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2576 BPF_LD_MAP_FD(BPF_REG_1, 0), 2577 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2578 BPF_FUNC_map_lookup_elem), 2579 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 2580 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8), 2581 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 2582 offsetof(struct test_val, foo)), 2583 BPF_EXIT_INSN(), 2584 }, 2585 .fixup_map2 = { 3, 11 }, 2586 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2587 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 2588 .result_unpriv = REJECT, 2589 .result = REJECT, 2590 }, 2591 { 2592 "multiple registers share map_lookup_elem result", 2593 .insns = { 2594 BPF_MOV64_IMM(BPF_REG_1, 10), 2595 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 2596 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2597 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2598 BPF_LD_MAP_FD(BPF_REG_1, 0), 2599 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2600 BPF_FUNC_map_lookup_elem), 2601 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 2602 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2603 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0), 2604 BPF_EXIT_INSN(), 2605 }, 2606 .fixup_map1 = { 4 }, 2607 .result = ACCEPT, 2608 .prog_type = BPF_PROG_TYPE_SCHED_CLS 2609 }, 2610 { 2611 "invalid memory access with multiple map_lookup_elem calls", 2612 .insns = { 2613 BPF_MOV64_IMM(BPF_REG_1, 10), 2614 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 2615 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2616 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2617 BPF_LD_MAP_FD(BPF_REG_1, 0), 2618 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1), 2619 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 2620 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2621 BPF_FUNC_map_lookup_elem), 2622 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 2623 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), 2624 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 2625 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2626 BPF_FUNC_map_lookup_elem), 2627 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2628 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0), 2629 BPF_EXIT_INSN(), 2630 }, 2631 .fixup_map1 = { 4 }, 2632 .result = REJECT, 2633 .errstr = "R4 !read_ok", 2634 .prog_type = BPF_PROG_TYPE_SCHED_CLS 2635 }, 2636 { 2637 "valid indirect map_lookup_elem access with 2nd lookup in branch", 2638 .insns = { 2639 BPF_MOV64_IMM(BPF_REG_1, 10), 2640 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 2641 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2643 BPF_LD_MAP_FD(BPF_REG_1, 0), 2644 BPF_MOV64_REG(BPF_REG_8, BPF_REG_1), 2645 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 2646 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2647 BPF_FUNC_map_lookup_elem), 2648 BPF_MOV64_IMM(BPF_REG_2, 10), 2649 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 3), 2650 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), 2651 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 2652 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2653 BPF_FUNC_map_lookup_elem), 2654 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 2655 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2656 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0), 2657 BPF_EXIT_INSN(), 2658 }, 2659 .fixup_map1 = { 4 }, 2660 .result = ACCEPT, 2661 .prog_type = BPF_PROG_TYPE_SCHED_CLS 2662 }, 2663 { 2664 "invalid map access from else condition", 2665 .insns = { 2666 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2667 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2668 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2669 BPF_LD_MAP_FD(BPF_REG_1, 0), 2670 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 2671 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), 2672 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), 2673 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES-1, 1), 2674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1), 2675 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2), 2676 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 2677 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)), 2678 BPF_EXIT_INSN(), 2679 }, 2680 .fixup_map2 = { 3 }, 2681 .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map", 2682 .result = REJECT, 2683 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2684 .result_unpriv = REJECT, 2685 }, 2686 }; 2687 2688 static int probe_filter_length(const struct bpf_insn *fp) 2689 { 2690 int len; 2691 2692 for (len = MAX_INSNS - 1; len > 0; --len) 2693 if (fp[len].code != 0 || fp[len].imm != 0) 2694 break; 2695 return len + 1; 2696 } 2697 2698 static int create_map(uint32_t size_value, uint32_t max_elem) 2699 { 2700 int fd; 2701 2702 fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(long long), 2703 size_value, max_elem, BPF_F_NO_PREALLOC); 2704 if (fd < 0) 2705 printf("Failed to create hash map '%s'!\n", strerror(errno)); 2706 2707 return fd; 2708 } 2709 2710 static int create_prog_array(void) 2711 { 2712 int fd; 2713 2714 fd = bpf_map_create(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int), 2715 sizeof(int), 4, 0); 2716 if (fd < 0) 2717 printf("Failed to create prog array '%s'!\n", strerror(errno)); 2718 2719 return fd; 2720 } 2721 2722 static char bpf_vlog[32768]; 2723 2724 static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, 2725 int *fd_f1, int *fd_f2, int *fd_f3) 2726 { 2727 int *fixup_map1 = test->fixup_map1; 2728 int *fixup_map2 = test->fixup_map2; 2729 int *fixup_prog = test->fixup_prog; 2730 2731 /* Allocating HTs with 1 elem is fine here, since we only test 2732 * for verifier and not do a runtime lookup, so the only thing 2733 * that really matters is value size in this case. 2734 */ 2735 if (*fixup_map1) { 2736 *fd_f1 = create_map(sizeof(long long), 1); 2737 do { 2738 prog[*fixup_map1].imm = *fd_f1; 2739 fixup_map1++; 2740 } while (*fixup_map1); 2741 } 2742 2743 if (*fixup_map2) { 2744 *fd_f2 = create_map(sizeof(struct test_val), 1); 2745 do { 2746 prog[*fixup_map2].imm = *fd_f2; 2747 fixup_map2++; 2748 } while (*fixup_map2); 2749 } 2750 2751 if (*fixup_prog) { 2752 *fd_f3 = create_prog_array(); 2753 do { 2754 prog[*fixup_prog].imm = *fd_f3; 2755 fixup_prog++; 2756 } while (*fixup_prog); 2757 } 2758 } 2759 2760 static void do_test_single(struct bpf_test *test, bool unpriv, 2761 int *passes, int *errors) 2762 { 2763 struct bpf_insn *prog = test->insns; 2764 int prog_len = probe_filter_length(prog); 2765 int prog_type = test->prog_type; 2766 int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1; 2767 int fd_prog, expected_ret; 2768 const char *expected_err; 2769 2770 do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3); 2771 2772 fd_prog = bpf_prog_load(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, 2773 prog, prog_len * sizeof(struct bpf_insn), 2774 "GPL", bpf_vlog, sizeof(bpf_vlog)); 2775 2776 expected_ret = unpriv && test->result_unpriv != UNDEF ? 2777 test->result_unpriv : test->result; 2778 expected_err = unpriv && test->errstr_unpriv ? 2779 test->errstr_unpriv : test->errstr; 2780 if (expected_ret == ACCEPT) { 2781 if (fd_prog < 0) { 2782 printf("FAIL\nFailed to load prog '%s'!\n", 2783 strerror(errno)); 2784 goto fail_log; 2785 } 2786 } else { 2787 if (fd_prog >= 0) { 2788 printf("FAIL\nUnexpected success to load!\n"); 2789 goto fail_log; 2790 } 2791 if (!strstr(bpf_vlog, expected_err)) { 2792 printf("FAIL\nUnexpected error message!\n"); 2793 goto fail_log; 2794 } 2795 } 2796 2797 (*passes)++; 2798 printf("OK\n"); 2799 close_fds: 2800 close(fd_prog); 2801 close(fd_f1); 2802 close(fd_f2); 2803 close(fd_f3); 2804 sched_yield(); 2805 return; 2806 fail_log: 2807 (*errors)++; 2808 printf("%s", bpf_vlog); 2809 goto close_fds; 2810 } 2811 2812 static int do_test(bool unpriv, unsigned int from, unsigned int to) 2813 { 2814 int i, passes = 0, errors = 0; 2815 2816 for (i = from; i < to; i++) { 2817 struct bpf_test *test = &tests[i]; 2818 2819 /* Program types that are not supported by non-root we 2820 * skip right away. 2821 */ 2822 if (unpriv && test->prog_type) 2823 continue; 2824 2825 printf("#%d %s ", i, test->descr); 2826 do_test_single(test, unpriv, &passes, &errors); 2827 } 2828 2829 printf("Summary: %d PASSED, %d FAILED\n", passes, errors); 2830 return errors ? -errors : 0; 2831 } 2832 2833 int main(int argc, char **argv) 2834 { 2835 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY }; 2836 struct rlimit rlim = { 1 << 20, 1 << 20 }; 2837 unsigned int from = 0, to = ARRAY_SIZE(tests); 2838 bool unpriv = geteuid() != 0; 2839 2840 if (argc == 3) { 2841 unsigned int l = atoi(argv[argc - 2]); 2842 unsigned int u = atoi(argv[argc - 1]); 2843 2844 if (l < to && u < to) { 2845 from = l; 2846 to = u + 1; 2847 } 2848 } else if (argc == 2) { 2849 unsigned int t = atoi(argv[argc - 1]); 2850 2851 if (t < to) { 2852 from = t; 2853 to = t + 1; 2854 } 2855 } 2856 2857 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf); 2858 return do_test(unpriv, from, to); 2859 } 2860