linux/samples/bpf/test_verifier.c
<<
>>
Prefs
   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}
2530