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 },