root/tools/testing/selftests/bpf/verifier/bounds.c

/* [<][>][^][v][top][bottom][index][help] */
   1 {
   2         "subtraction bounds (map value) variant 1",
   3         .insns = {
   4         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
   5         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
   6         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
   7         BPF_LD_MAP_FD(BPF_REG_1, 0),
   8         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
   9         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
  10         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
  11         BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
  12         BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
  13         BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
  14         BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
  15         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
  16         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
  17         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
  18         BPF_EXIT_INSN(),
  19         BPF_MOV64_IMM(BPF_REG_0, 0),
  20         BPF_EXIT_INSN(),
  21         },
  22         .fixup_map_hash_8b = { 3 },
  23         .errstr = "R0 max value is outside of the array range",
  24         .result = REJECT,
  25 },
  26 {
  27         "subtraction bounds (map value) variant 2",
  28         .insns = {
  29         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  30         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  31         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  32         BPF_LD_MAP_FD(BPF_REG_1, 0),
  33         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  34         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
  35         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
  36         BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
  37         BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
  38         BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
  39         BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
  40         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
  41         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
  42         BPF_EXIT_INSN(),
  43         BPF_MOV64_IMM(BPF_REG_0, 0),
  44         BPF_EXIT_INSN(),
  45         },
  46         .fixup_map_hash_8b = { 3 },
  47         .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
  48         .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds",
  49         .result = REJECT,
  50 },
  51 {
  52         "check subtraction on pointers for unpriv",
  53         .insns = {
  54         BPF_MOV64_IMM(BPF_REG_0, 0),
  55         BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
  56         BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
  57         BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
  58         BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 9),
  59         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  60         BPF_MOV64_REG(BPF_REG_9, BPF_REG_FP),
  61         BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_0),
  62         BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
  63         BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
  64         BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
  65         BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 0),
  66         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  67         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  68         BPF_EXIT_INSN(),
  69         BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
  70         BPF_MOV64_IMM(BPF_REG_0, 0),
  71         BPF_EXIT_INSN(),
  72         },
  73         .fixup_map_hash_8b = { 1, 9 },
  74         .result = ACCEPT,
  75         .result_unpriv = REJECT,
  76         .errstr_unpriv = "R9 pointer -= pointer prohibited",
  77 },
  78 {
  79         "bounds check based on zero-extended MOV",
  80         .insns = {
  81         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  82         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  83         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  84         BPF_LD_MAP_FD(BPF_REG_1, 0),
  85         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  86         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
  87         /* r2 = 0x0000'0000'ffff'ffff */
  88         BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
  89         /* r2 = 0 */
  90         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
  91         /* no-op */
  92         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
  93         /* access at offset 0 */
  94         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
  95         /* exit */
  96         BPF_MOV64_IMM(BPF_REG_0, 0),
  97         BPF_EXIT_INSN(),
  98         },
  99         .fixup_map_hash_8b = { 3 },
 100         .result = ACCEPT
 101 },
 102 {
 103         "bounds check based on sign-extended MOV. test1",
 104         .insns = {
 105         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 106         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 107         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 108         BPF_LD_MAP_FD(BPF_REG_1, 0),
 109         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 110         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 111         /* r2 = 0xffff'ffff'ffff'ffff */
 112         BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
 113         /* r2 = 0xffff'ffff */
 114         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
 115         /* r0 = <oob pointer> */
 116         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
 117         /* access to OOB pointer */
 118         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 119         /* exit */
 120         BPF_MOV64_IMM(BPF_REG_0, 0),
 121         BPF_EXIT_INSN(),
 122         },
 123         .fixup_map_hash_8b = { 3 },
 124         .errstr = "map_value pointer and 4294967295",
 125         .result = REJECT
 126 },
 127 {
 128         "bounds check based on sign-extended MOV. test2",
 129         .insns = {
 130         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 131         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 132         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 133         BPF_LD_MAP_FD(BPF_REG_1, 0),
 134         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 135         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 136         /* r2 = 0xffff'ffff'ffff'ffff */
 137         BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
 138         /* r2 = 0xfff'ffff */
 139         BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
 140         /* r0 = <oob pointer> */
 141         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
 142         /* access to OOB pointer */
 143         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 144         /* exit */
 145         BPF_MOV64_IMM(BPF_REG_0, 0),
 146         BPF_EXIT_INSN(),
 147         },
 148         .fixup_map_hash_8b = { 3 },
 149         .errstr = "R0 min value is outside of the array range",
 150         .result = REJECT
 151 },
 152 {
 153         "bounds check based on reg_off + var_off + insn_off. test1",
 154         .insns = {
 155         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
 156                     offsetof(struct __sk_buff, mark)),
 157         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 158         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 159         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 160         BPF_LD_MAP_FD(BPF_REG_1, 0),
 161         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 162         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 163         BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
 164         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
 165         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
 166         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
 167         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
 168         BPF_MOV64_IMM(BPF_REG_0, 0),
 169         BPF_EXIT_INSN(),
 170         },
 171         .fixup_map_hash_8b = { 4 },
 172         .errstr = "value_size=8 off=1073741825",
 173         .result = REJECT,
 174         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 175 },
 176 {
 177         "bounds check based on reg_off + var_off + insn_off. test2",
 178         .insns = {
 179         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
 180                     offsetof(struct __sk_buff, mark)),
 181         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 182         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 183         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 184         BPF_LD_MAP_FD(BPF_REG_1, 0),
 185         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 186         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 187         BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
 188         BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
 189         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
 190         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
 191         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
 192         BPF_MOV64_IMM(BPF_REG_0, 0),
 193         BPF_EXIT_INSN(),
 194         },
 195         .fixup_map_hash_8b = { 4 },
 196         .errstr = "value 1073741823",
 197         .result = REJECT,
 198         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 199 },
 200 {
 201         "bounds check after truncation of non-boundary-crossing range",
 202         .insns = {
 203         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 204         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 205         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 206         BPF_LD_MAP_FD(BPF_REG_1, 0),
 207         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 208         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
 209         /* r1 = [0x00, 0xff] */
 210         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 211         BPF_MOV64_IMM(BPF_REG_2, 1),
 212         /* r2 = 0x10'0000'0000 */
 213         BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
 214         /* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
 215         BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
 216         /* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
 217         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
 218         /* r1 = [0x00, 0xff] */
 219         BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
 220         /* r1 = 0 */
 221         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 222         /* no-op */
 223         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 224         /* access at offset 0 */
 225         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 226         /* exit */
 227         BPF_MOV64_IMM(BPF_REG_0, 0),
 228         BPF_EXIT_INSN(),
 229         },
 230         .fixup_map_hash_8b = { 3 },
 231         .result = ACCEPT
 232 },
 233 {
 234         "bounds check after truncation of boundary-crossing range (1)",
 235         .insns = {
 236         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 237         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 238         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 239         BPF_LD_MAP_FD(BPF_REG_1, 0),
 240         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 241         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
 242         /* r1 = [0x00, 0xff] */
 243         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 244         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
 245         /* r1 = [0xffff'ff80, 0x1'0000'007f] */
 246         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
 247         /* r1 = [0xffff'ff80, 0xffff'ffff] or
 248          *      [0x0000'0000, 0x0000'007f]
 249          */
 250         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
 251         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
 252         /* r1 = [0x00, 0xff] or
 253          *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
 254          */
 255         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
 256         /* r1 = 0 or
 257          *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
 258          */
 259         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 260         /* no-op or OOB pointer computation */
 261         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 262         /* potentially OOB access */
 263         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 264         /* exit */
 265         BPF_MOV64_IMM(BPF_REG_0, 0),
 266         BPF_EXIT_INSN(),
 267         },
 268         .fixup_map_hash_8b = { 3 },
 269         /* not actually fully unbounded, but the bound is very high */
 270         .errstr = "R0 unbounded memory access",
 271         .result = REJECT
 272 },
 273 {
 274         "bounds check after truncation of boundary-crossing range (2)",
 275         .insns = {
 276         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 277         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 278         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 279         BPF_LD_MAP_FD(BPF_REG_1, 0),
 280         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 281         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
 282         /* r1 = [0x00, 0xff] */
 283         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 284         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
 285         /* r1 = [0xffff'ff80, 0x1'0000'007f] */
 286         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
 287         /* r1 = [0xffff'ff80, 0xffff'ffff] or
 288          *      [0x0000'0000, 0x0000'007f]
 289          * difference to previous test: truncation via MOV32
 290          * instead of ALU32.
 291          */
 292         BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
 293         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
 294         /* r1 = [0x00, 0xff] or
 295          *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
 296          */
 297         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
 298         /* r1 = 0 or
 299          *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
 300          */
 301         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 302         /* no-op or OOB pointer computation */
 303         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 304         /* potentially OOB access */
 305         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 306         /* exit */
 307         BPF_MOV64_IMM(BPF_REG_0, 0),
 308         BPF_EXIT_INSN(),
 309         },
 310         .fixup_map_hash_8b = { 3 },
 311         /* not actually fully unbounded, but the bound is very high */
 312         .errstr = "R0 unbounded memory access",
 313         .result = REJECT
 314 },
 315 {
 316         "bounds check after wrapping 32-bit addition",
 317         .insns = {
 318         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 319         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 320         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 321         BPF_LD_MAP_FD(BPF_REG_1, 0),
 322         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 323         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
 324         /* r1 = 0x7fff'ffff */
 325         BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
 326         /* r1 = 0xffff'fffe */
 327         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
 328         /* r1 = 0 */
 329         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
 330         /* no-op */
 331         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 332         /* access at offset 0 */
 333         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 334         /* exit */
 335         BPF_MOV64_IMM(BPF_REG_0, 0),
 336         BPF_EXIT_INSN(),
 337         },
 338         .fixup_map_hash_8b = { 3 },
 339         .result = ACCEPT
 340 },
 341 {
 342         "bounds check after shift with oversized count operand",
 343         .insns = {
 344         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 345         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 346         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 347         BPF_LD_MAP_FD(BPF_REG_1, 0),
 348         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 349         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 350         BPF_MOV64_IMM(BPF_REG_2, 32),
 351         BPF_MOV64_IMM(BPF_REG_1, 1),
 352         /* r1 = (u32)1 << (u32)32 = ? */
 353         BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
 354         /* r1 = [0x0000, 0xffff] */
 355         BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
 356         /* computes unknown pointer, potentially OOB */
 357         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 358         /* potentially OOB access */
 359         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 360         /* exit */
 361         BPF_MOV64_IMM(BPF_REG_0, 0),
 362         BPF_EXIT_INSN(),
 363         },
 364         .fixup_map_hash_8b = { 3 },
 365         .errstr = "R0 max value is outside of the array range",
 366         .result = REJECT
 367 },
 368 {
 369         "bounds check after right shift of maybe-negative number",
 370         .insns = {
 371         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 372         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 373         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 374         BPF_LD_MAP_FD(BPF_REG_1, 0),
 375         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 376         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 377         /* r1 = [0x00, 0xff] */
 378         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 379         /* r1 = [-0x01, 0xfe] */
 380         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
 381         /* r1 = 0 or 0xff'ffff'ffff'ffff */
 382         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 383         /* r1 = 0 or 0xffff'ffff'ffff */
 384         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 385         /* computes unknown pointer, potentially OOB */
 386         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 387         /* potentially OOB access */
 388         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 389         /* exit */
 390         BPF_MOV64_IMM(BPF_REG_0, 0),
 391         BPF_EXIT_INSN(),
 392         },
 393         .fixup_map_hash_8b = { 3 },
 394         .errstr = "R0 unbounded memory access",
 395         .result = REJECT
 396 },
 397 {
 398         "bounds check after 32-bit right shift with 64-bit input",
 399         .insns = {
 400         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 401         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 402         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 403         BPF_LD_MAP_FD(BPF_REG_1, 0),
 404         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 405         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 406         /* r1 = 2 */
 407         BPF_MOV64_IMM(BPF_REG_1, 2),
 408         /* r1 = 1<<32 */
 409         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 31),
 410         /* r1 = 0 (NOT 2!) */
 411         BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 31),
 412         /* r1 = 0xffff'fffe (NOT 0!) */
 413         BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 2),
 414         /* computes OOB pointer */
 415         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 416         /* OOB access */
 417         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 418         /* exit */
 419         BPF_MOV64_IMM(BPF_REG_0, 0),
 420         BPF_EXIT_INSN(),
 421         },
 422         .fixup_map_hash_8b = { 3 },
 423         .errstr = "R0 invalid mem access",
 424         .result = REJECT,
 425 },
 426 {
 427         "bounds check map access with off+size signed 32bit overflow. test1",
 428         .insns = {
 429         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 430         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 431         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 432         BPF_LD_MAP_FD(BPF_REG_1, 0),
 433         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 434         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 435         BPF_EXIT_INSN(),
 436         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
 437         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
 438         BPF_JMP_A(0),
 439         BPF_EXIT_INSN(),
 440         },
 441         .fixup_map_hash_8b = { 3 },
 442         .errstr = "map_value pointer and 2147483646",
 443         .result = REJECT
 444 },
 445 {
 446         "bounds check map access with off+size signed 32bit overflow. test2",
 447         .insns = {
 448         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 449         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 450         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 451         BPF_LD_MAP_FD(BPF_REG_1, 0),
 452         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 453         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 454         BPF_EXIT_INSN(),
 455         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
 456         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
 457         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
 458         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
 459         BPF_JMP_A(0),
 460         BPF_EXIT_INSN(),
 461         },
 462         .fixup_map_hash_8b = { 3 },
 463         .errstr = "pointer offset 1073741822",
 464         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
 465         .result = REJECT
 466 },
 467 {
 468         "bounds check map access with off+size signed 32bit overflow. test3",
 469         .insns = {
 470         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 471         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 472         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 473         BPF_LD_MAP_FD(BPF_REG_1, 0),
 474         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 475         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 476         BPF_EXIT_INSN(),
 477         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
 478         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
 479         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
 480         BPF_JMP_A(0),
 481         BPF_EXIT_INSN(),
 482         },
 483         .fixup_map_hash_8b = { 3 },
 484         .errstr = "pointer offset -1073741822",
 485         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
 486         .result = REJECT
 487 },
 488 {
 489         "bounds check map access with off+size signed 32bit overflow. test4",
 490         .insns = {
 491         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 492         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 493         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 494         BPF_LD_MAP_FD(BPF_REG_1, 0),
 495         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 496         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 497         BPF_EXIT_INSN(),
 498         BPF_MOV64_IMM(BPF_REG_1, 1000000),
 499         BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
 500         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 501         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
 502         BPF_JMP_A(0),
 503         BPF_EXIT_INSN(),
 504         },
 505         .fixup_map_hash_8b = { 3 },
 506         .errstr = "map_value pointer and 1000000000000",
 507         .result = REJECT
 508 },

/* [<][>][^][v][top][bottom][index][help] */