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