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

/* [<][>][^][v][top][bottom][index][help] */
   1 {
   2         "valid map access into an array with a constant",
   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, 1),
  10         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
  11         BPF_EXIT_INSN(),
  12         },
  13         .fixup_map_hash_48b = { 3 },
  14         .errstr_unpriv = "R0 leaks addr",
  15         .result_unpriv = REJECT,
  16         .result = ACCEPT,
  17 },
  18 {
  19         "valid map access into an array with a register",
  20         .insns = {
  21         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  22         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  23         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  24         BPF_LD_MAP_FD(BPF_REG_1, 0),
  25         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  26         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
  27         BPF_MOV64_IMM(BPF_REG_1, 4),
  28         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
  29         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
  30         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
  31         BPF_EXIT_INSN(),
  32         },
  33         .fixup_map_hash_48b = { 3 },
  34         .errstr_unpriv = "R0 leaks addr",
  35         .result_unpriv = REJECT,
  36         .result = ACCEPT,
  37         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
  38 },
  39 {
  40         "valid map access into an array with a variable",
  41         .insns = {
  42         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  43         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  44         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  45         BPF_LD_MAP_FD(BPF_REG_1, 0),
  46         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  47         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
  48         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
  49         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
  50         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
  51         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
  52         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
  53         BPF_EXIT_INSN(),
  54         },
  55         .fixup_map_hash_48b = { 3 },
  56         .errstr_unpriv = "R0 leaks addr",
  57         .result_unpriv = REJECT,
  58         .result = ACCEPT,
  59         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
  60 },
  61 {
  62         "valid map access into an array with a signed variable",
  63         .insns = {
  64         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  65         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  66         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  67         BPF_LD_MAP_FD(BPF_REG_1, 0),
  68         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  69         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
  70         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
  71         BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
  72         BPF_MOV32_IMM(BPF_REG_1, 0),
  73         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
  74         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
  75         BPF_MOV32_IMM(BPF_REG_1, 0),
  76         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
  77         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
  78         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
  79         BPF_EXIT_INSN(),
  80         },
  81         .fixup_map_hash_48b = { 3 },
  82         .errstr_unpriv = "R0 leaks addr",
  83         .result_unpriv = REJECT,
  84         .result = ACCEPT,
  85         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
  86 },
  87 {
  88         "invalid map access into an array with a constant",
  89         .insns = {
  90         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  91         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  92         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  93         BPF_LD_MAP_FD(BPF_REG_1, 0),
  94         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  95         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
  96         BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
  97                    offsetof(struct test_val, foo)),
  98         BPF_EXIT_INSN(),
  99         },
 100         .fixup_map_hash_48b = { 3 },
 101         .errstr = "invalid access to map value, value_size=48 off=48 size=8",
 102         .result = REJECT,
 103 },
 104 {
 105         "invalid map access into an array with a register",
 106         .insns = {
 107         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 108         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 109         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 110         BPF_LD_MAP_FD(BPF_REG_1, 0),
 111         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 112         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 113         BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
 114         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
 115         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 116         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
 117         BPF_EXIT_INSN(),
 118         },
 119         .fixup_map_hash_48b = { 3 },
 120         .errstr = "R0 min value is outside of the array range",
 121         .result = REJECT,
 122         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 123 },
 124 {
 125         "invalid map access into an array with a variable",
 126         .insns = {
 127         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 128         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 129         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 130         BPF_LD_MAP_FD(BPF_REG_1, 0),
 131         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 132         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 133         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
 134         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
 135         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 136         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
 137         BPF_EXIT_INSN(),
 138         },
 139         .fixup_map_hash_48b = { 3 },
 140         .errstr = "R0 unbounded memory access, make sure to bounds check any array access into a map",
 141         .result = REJECT,
 142         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 143 },
 144 {
 145         "invalid map access into an array with no floor check",
 146         .insns = {
 147         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 148         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 149         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 150         BPF_LD_MAP_FD(BPF_REG_1, 0),
 151         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 152         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
 153         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
 154         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
 155         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
 156         BPF_MOV32_IMM(BPF_REG_1, 0),
 157         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
 158         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 159         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
 160         BPF_EXIT_INSN(),
 161         },
 162         .fixup_map_hash_48b = { 3 },
 163         .errstr_unpriv = "R0 leaks addr",
 164         .errstr = "R0 unbounded memory access",
 165         .result_unpriv = REJECT,
 166         .result = REJECT,
 167         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 168 },
 169 {
 170         "invalid map access into an array with a invalid max check",
 171         .insns = {
 172         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 173         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 174         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 175         BPF_LD_MAP_FD(BPF_REG_1, 0),
 176         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 177         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
 178         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
 179         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
 180         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
 181         BPF_MOV32_IMM(BPF_REG_1, 0),
 182         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
 183         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 184         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
 185         BPF_EXIT_INSN(),
 186         },
 187         .fixup_map_hash_48b = { 3 },
 188         .errstr_unpriv = "R0 leaks addr",
 189         .errstr = "invalid access to map value, value_size=48 off=44 size=8",
 190         .result_unpriv = REJECT,
 191         .result = REJECT,
 192         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 193 },
 194 {
 195         "invalid map access into an array with a invalid max check",
 196         .insns = {
 197         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 198         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 199         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 200         BPF_LD_MAP_FD(BPF_REG_1, 0),
 201         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 202         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
 203         BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
 204         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 205         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 206         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 207         BPF_LD_MAP_FD(BPF_REG_1, 0),
 208         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 209         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
 210         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
 211         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
 212                     offsetof(struct test_val, foo)),
 213         BPF_EXIT_INSN(),
 214         },
 215         .fixup_map_hash_48b = { 3, 11 },
 216         .errstr = "R0 pointer += pointer",
 217         .result = REJECT,
 218         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 219 },
 220 {
 221         "valid read map access into a read-only array 1",
 222         .insns = {
 223         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 224         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 225         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 226         BPF_LD_MAP_FD(BPF_REG_1, 0),
 227         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 228         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
 229         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
 230         BPF_EXIT_INSN(),
 231         },
 232         .fixup_map_array_ro = { 3 },
 233         .result = ACCEPT,
 234         .retval = 28,
 235 },
 236 {
 237         "valid read map access into a read-only array 2",
 238         .insns = {
 239         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 240         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 241         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 242         BPF_LD_MAP_FD(BPF_REG_1, 0),
 243         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 244         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 245 
 246         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
 247         BPF_MOV64_IMM(BPF_REG_2, 4),
 248         BPF_MOV64_IMM(BPF_REG_3, 0),
 249         BPF_MOV64_IMM(BPF_REG_4, 0),
 250         BPF_MOV64_IMM(BPF_REG_5, 0),
 251         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
 252                      BPF_FUNC_csum_diff),
 253         BPF_EXIT_INSN(),
 254         },
 255         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 256         .fixup_map_array_ro = { 3 },
 257         .result = ACCEPT,
 258         .retval = -29,
 259 },
 260 {
 261         "invalid write map access into a read-only array 1",
 262         .insns = {
 263         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 264         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 265         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 266         BPF_LD_MAP_FD(BPF_REG_1, 0),
 267         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 268         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
 269         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
 270         BPF_EXIT_INSN(),
 271         },
 272         .fixup_map_array_ro = { 3 },
 273         .result = REJECT,
 274         .errstr = "write into map forbidden",
 275 },
 276 {
 277         "invalid write map access into a read-only array 2",
 278         .insns = {
 279         BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
 280         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 281         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 282         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 283         BPF_LD_MAP_FD(BPF_REG_1, 0),
 284         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 285         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
 286         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
 287         BPF_MOV64_IMM(BPF_REG_2, 0),
 288         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
 289         BPF_MOV64_IMM(BPF_REG_4, 8),
 290         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
 291                      BPF_FUNC_skb_load_bytes),
 292         BPF_EXIT_INSN(),
 293         },
 294         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 295         .fixup_map_array_ro = { 4 },
 296         .result = REJECT,
 297         .errstr = "write into map forbidden",
 298 },
 299 {
 300         "valid write map access into a write-only array 1",
 301         .insns = {
 302         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 303         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 304         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 305         BPF_LD_MAP_FD(BPF_REG_1, 0),
 306         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 307         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
 308         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
 309         BPF_MOV64_IMM(BPF_REG_0, 1),
 310         BPF_EXIT_INSN(),
 311         },
 312         .fixup_map_array_wo = { 3 },
 313         .result = ACCEPT,
 314         .retval = 1,
 315 },
 316 {
 317         "valid write map access into a write-only array 2",
 318         .insns = {
 319         BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
 320         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 321         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 322         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 323         BPF_LD_MAP_FD(BPF_REG_1, 0),
 324         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 325         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
 326         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
 327         BPF_MOV64_IMM(BPF_REG_2, 0),
 328         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
 329         BPF_MOV64_IMM(BPF_REG_4, 8),
 330         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
 331                      BPF_FUNC_skb_load_bytes),
 332         BPF_EXIT_INSN(),
 333         },
 334         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 335         .fixup_map_array_wo = { 4 },
 336         .result = ACCEPT,
 337         .retval = 0,
 338 },
 339 {
 340         "invalid read map access into a write-only array 1",
 341         .insns = {
 342         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 343         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 344         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 345         BPF_LD_MAP_FD(BPF_REG_1, 0),
 346         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 347         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
 348         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
 349         BPF_EXIT_INSN(),
 350         },
 351         .fixup_map_array_wo = { 3 },
 352         .result = REJECT,
 353         .errstr = "read from map forbidden",
 354 },
 355 {
 356         "invalid read map access into a write-only array 2",
 357         .insns = {
 358         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 359         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 360         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 361         BPF_LD_MAP_FD(BPF_REG_1, 0),
 362         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 363         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 364 
 365         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
 366         BPF_MOV64_IMM(BPF_REG_2, 4),
 367         BPF_MOV64_IMM(BPF_REG_3, 0),
 368         BPF_MOV64_IMM(BPF_REG_4, 0),
 369         BPF_MOV64_IMM(BPF_REG_5, 0),
 370         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
 371                      BPF_FUNC_csum_diff),
 372         BPF_EXIT_INSN(),
 373         },
 374         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
 375         .fixup_map_array_wo = { 3 },
 376         .result = REJECT,
 377         .errstr = "read from map forbidden",
 378 },

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