array_access.c (12358B)
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_JMP32_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 allowed memory 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 such access", 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_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff), 254 BPF_EXIT_INSN(), 255 }, 256 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 257 .fixup_map_array_ro = { 3 }, 258 .result = ACCEPT, 259 .retval = 65507, 260}, 261{ 262 "invalid write map access into a read-only array 1", 263 .insns = { 264 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 265 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 266 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 267 BPF_LD_MAP_FD(BPF_REG_1, 0), 268 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 269 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 270 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), 271 BPF_EXIT_INSN(), 272 }, 273 .fixup_map_array_ro = { 3 }, 274 .result = REJECT, 275 .errstr = "write into map forbidden", 276}, 277{ 278 "invalid write map access into a read-only array 2", 279 .insns = { 280 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 281 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 282 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 284 BPF_LD_MAP_FD(BPF_REG_1, 0), 285 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 286 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), 287 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 288 BPF_MOV64_IMM(BPF_REG_2, 0), 289 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 290 BPF_MOV64_IMM(BPF_REG_4, 8), 291 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 292 BPF_FUNC_skb_load_bytes), 293 BPF_EXIT_INSN(), 294 }, 295 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 296 .fixup_map_array_ro = { 4 }, 297 .result = REJECT, 298 .errstr = "write into map forbidden", 299}, 300{ 301 "valid write map access into a write-only array 1", 302 .insns = { 303 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 304 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 305 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 306 BPF_LD_MAP_FD(BPF_REG_1, 0), 307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 308 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 309 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), 310 BPF_MOV64_IMM(BPF_REG_0, 1), 311 BPF_EXIT_INSN(), 312 }, 313 .fixup_map_array_wo = { 3 }, 314 .result = ACCEPT, 315 .retval = 1, 316}, 317{ 318 "valid write map access into a write-only array 2", 319 .insns = { 320 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 321 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 322 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 324 BPF_LD_MAP_FD(BPF_REG_1, 0), 325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 326 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), 327 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 328 BPF_MOV64_IMM(BPF_REG_2, 0), 329 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 330 BPF_MOV64_IMM(BPF_REG_4, 8), 331 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 332 BPF_FUNC_skb_load_bytes), 333 BPF_EXIT_INSN(), 334 }, 335 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 336 .fixup_map_array_wo = { 4 }, 337 .result = ACCEPT, 338 .retval = 0, 339}, 340{ 341 "invalid read map access into a write-only array 1", 342 .insns = { 343 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 344 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 346 BPF_LD_MAP_FD(BPF_REG_1, 0), 347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 348 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 349 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), 350 BPF_EXIT_INSN(), 351 }, 352 .fixup_map_array_wo = { 3 }, 353 .result = REJECT, 354 .errstr = "read from map forbidden", 355}, 356{ 357 "invalid read map access into a write-only array 2", 358 .insns = { 359 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 360 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 362 BPF_LD_MAP_FD(BPF_REG_1, 0), 363 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 364 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), 365 366 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 367 BPF_MOV64_IMM(BPF_REG_2, 4), 368 BPF_MOV64_IMM(BPF_REG_3, 0), 369 BPF_MOV64_IMM(BPF_REG_4, 0), 370 BPF_MOV64_IMM(BPF_REG_5, 0), 371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 372 BPF_FUNC_csum_diff), 373 BPF_EXIT_INSN(), 374 }, 375 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 376 .fixup_map_array_wo = { 3 }, 377 .result = REJECT, 378 .errstr = "read from map forbidden", 379},