1 { 2 "calls: invalid kfunc call not eliminated", 3 .insns = { 4 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 5 BPF_MOV64_IMM(BPF_REG_0, 1), 6 BPF_EXIT_INSN(), 7 }, 8 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 9 .result = REJECT, 10 .errstr = "invalid kernel function call not eliminated in verifier pass", 11 }, 12 { 13 "calls: invalid kfunc call unreachable", 14 .insns = { 15 BPF_MOV64_IMM(BPF_REG_0, 1), 16 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 0, 2), 17 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 18 BPF_MOV64_IMM(BPF_REG_0, 1), 19 BPF_EXIT_INSN(), 20 }, 21 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 22 .result = ACCEPT, 23 }, 24 { 25 "calls: invalid kfunc call: ptr_to_mem to struct with non-scalar", 26 .insns = { 27 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 28 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 29 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 30 BPF_EXIT_INSN(), 31 }, 32 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 33 .result = REJECT, 34 .errstr = "R1 is fp expected STRUCT prog_test_fail1", 35 .fixup_kfunc_btf_id = { 36 { "bpf_kfunc_call_test_fail1", 2 }, 37 }, 38 }, 39 { 40 "calls: invalid kfunc call: ptr_to_mem to struct with nesting depth > 4", 41 .insns = { 42 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 43 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 44 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 45 BPF_EXIT_INSN(), 46 }, 47 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 48 .result = REJECT, 49 .errstr = "max struct nesting depth exceeded\nR1 is fp expected STRUCT prog_test_fail2", 50 .fixup_kfunc_btf_id = { 51 { "bpf_kfunc_call_test_fail2", 2 }, 52 }, 53 }, 54 { 55 "calls: invalid kfunc call: ptr_to_mem to struct with FAM", 56 .insns = { 57 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 58 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 59 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 60 BPF_EXIT_INSN(), 61 }, 62 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 63 .result = REJECT, 64 .errstr = "R1 is fp expected STRUCT prog_test_fail3", 65 .fixup_kfunc_btf_id = { 66 { "bpf_kfunc_call_test_fail3", 2 }, 67 }, 68 }, 69 { 70 "calls: invalid kfunc call: reg->type != PTR_TO_CTX", 71 .insns = { 72 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 73 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 74 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 75 BPF_EXIT_INSN(), 76 }, 77 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 78 .result = REJECT, 79 .errstr = "R1 expected pointer to ctx, but got fp", 80 .fixup_kfunc_btf_id = { 81 { "bpf_kfunc_call_test_pass_ctx", 2 }, 82 }, 83 }, 84 { 85 "calls: invalid kfunc call: void * not allowed in func proto without mem size arg", 86 .insns = { 87 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 88 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 89 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 90 BPF_EXIT_INSN(), 91 }, 92 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 93 .result = REJECT, 94 .errstr = "R1 pointer type UNKNOWN must point to scalar", 95 .fixup_kfunc_btf_id = { 96 { "bpf_kfunc_call_test_mem_len_fail1", 2 }, 97 }, 98 }, 99 { 100 "calls: trigger reg2btf_ids[reg->type] for reg->type > __BPF_REG_TYPE_MAX", 101 .insns = { 102 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 104 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 105 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 106 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 107 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 108 BPF_EXIT_INSN(), 109 }, 110 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 111 .result = REJECT, 112 .errstr = "Possibly NULL pointer passed to trusted R1", 113 .fixup_kfunc_btf_id = { 114 { "bpf_kfunc_call_test_acquire", 3 }, 115 { "bpf_kfunc_call_test_release", 5 }, 116 }, 117 }, 118 { 119 "calls: invalid kfunc call: reg->off must be zero when passed to release kfunc", 120 .insns = { 121 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 122 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 123 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 124 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 125 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 126 BPF_EXIT_INSN(), 127 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 128 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 129 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 130 BPF_MOV64_IMM(BPF_REG_0, 0), 131 BPF_EXIT_INSN(), 132 }, 133 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 134 .result = REJECT, 135 .errstr = "R1 must have zero offset when passed to release func", 136 .fixup_kfunc_btf_id = { 137 { "bpf_kfunc_call_test_acquire", 3 }, 138 { "bpf_kfunc_call_memb_release", 8 }, 139 }, 140 }, 141 { 142 "calls: invalid kfunc call: don't match first member type when passed to release kfunc", 143 .insns = { 144 BPF_MOV64_IMM(BPF_REG_0, 0), 145 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 146 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 147 BPF_EXIT_INSN(), 148 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 149 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 150 BPF_MOV64_IMM(BPF_REG_0, 0), 151 BPF_EXIT_INSN(), 152 }, 153 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 154 .result = REJECT, 155 .errstr = "kernel function bpf_kfunc_call_memb1_release R1 expected pointer", 156 .fixup_kfunc_btf_id = { 157 { "bpf_kfunc_call_memb_acquire", 1 }, 158 { "bpf_kfunc_call_memb1_release", 5 }, 159 }, 160 }, 161 { 162 "calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset", 163 .insns = { 164 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 165 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 166 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 167 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 168 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 169 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 170 BPF_EXIT_INSN(), 171 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 172 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4), 173 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 174 BPF_MOV64_IMM(BPF_REG_0, 0), 175 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 176 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 177 BPF_MOV64_IMM(BPF_REG_0, 0), 178 BPF_EXIT_INSN(), 179 }, 180 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 181 .fixup_kfunc_btf_id = { 182 { "bpf_kfunc_call_test_acquire", 3 }, 183 { "bpf_kfunc_call_test_offset", 9 }, 184 { "bpf_kfunc_call_test_release", 12 }, 185 }, 186 .result_unpriv = REJECT, 187 .result = REJECT, 188 .errstr = "ptr R1 off=-4 disallowed", 189 }, 190 { 191 "calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset", 192 .insns = { 193 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 194 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 195 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 197 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 198 BPF_EXIT_INSN(), 199 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 200 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4), 201 BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3), 202 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 203 BPF_MOV64_IMM(BPF_REG_0, 0), 204 BPF_EXIT_INSN(), 205 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3), 206 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 207 BPF_MOV64_IMM(BPF_REG_0, 0), 208 BPF_EXIT_INSN(), 209 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 210 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 211 BPF_MOV64_IMM(BPF_REG_0, 0), 212 BPF_EXIT_INSN(), 213 }, 214 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 215 .fixup_kfunc_btf_id = { 216 { "bpf_kfunc_call_test_acquire", 3 }, 217 { "bpf_kfunc_call_test_release", 9 }, 218 { "bpf_kfunc_call_test_release", 13 }, 219 { "bpf_kfunc_call_test_release", 17 }, 220 }, 221 .result_unpriv = REJECT, 222 .result = REJECT, 223 .errstr = "R1 must have zero offset when passed to release func or trusted arg to kfunc", 224 }, 225 { 226 "calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID", 227 .insns = { 228 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 230 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 231 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 232 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 233 BPF_EXIT_INSN(), 234 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 235 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 236 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 237 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 16), 238 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 239 BPF_MOV64_IMM(BPF_REG_0, 0), 240 BPF_EXIT_INSN(), 241 }, 242 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 243 .fixup_kfunc_btf_id = { 244 { "bpf_kfunc_call_test_acquire", 3 }, 245 { "bpf_kfunc_call_test_ref", 8 }, 246 { "bpf_kfunc_call_test_ref", 10 }, 247 }, 248 .result_unpriv = REJECT, 249 .result = REJECT, 250 .errstr = "R1 must be", 251 }, 252 { 253 "calls: valid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID", 254 .insns = { 255 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 256 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 257 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 258 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 259 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 260 BPF_EXIT_INSN(), 261 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 262 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 263 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 264 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 265 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 266 BPF_MOV64_IMM(BPF_REG_0, 0), 267 BPF_EXIT_INSN(), 268 }, 269 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 270 .fixup_kfunc_btf_id = { 271 { "bpf_kfunc_call_test_acquire", 3 }, 272 { "bpf_kfunc_call_test_ref", 8 }, 273 { "bpf_kfunc_call_test_release", 10 }, 274 }, 275 .result_unpriv = REJECT, 276 .result = ACCEPT, 277 }, 278 { 279 "calls: invalid kfunc call: must provide (attach_prog_fd, btf_id) pair when freplace", 280 .insns = { 281 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 282 BPF_EXIT_INSN(), 283 }, 284 .prog_type = BPF_PROG_TYPE_EXT, 285 .result = REJECT, 286 .errstr = "Tracing programs must provide btf_id", 287 .fixup_kfunc_btf_id = { 288 { "bpf_dynptr_from_skb", 0 }, 289 }, 290 }, 291 { 292 "calls: basic sanity", 293 .insns = { 294 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 295 BPF_MOV64_IMM(BPF_REG_0, 1), 296 BPF_EXIT_INSN(), 297 BPF_MOV64_IMM(BPF_REG_0, 2), 298 BPF_EXIT_INSN(), 299 }, 300 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 301 .result = ACCEPT, 302 }, 303 { 304 "calls: not on unprivileged", 305 .insns = { 306 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 307 BPF_MOV64_IMM(BPF_REG_0, 1), 308 BPF_EXIT_INSN(), 309 BPF_MOV64_IMM(BPF_REG_0, 2), 310 BPF_EXIT_INSN(), 311 }, 312 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 313 .result_unpriv = REJECT, 314 .result = ACCEPT, 315 .retval = 1, 316 }, 317 { 318 "calls: div by 0 in subprog", 319 .insns = { 320 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 321 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 322 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 323 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 324 offsetof(struct __sk_buff, data_end)), 325 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 326 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 327 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 328 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 329 BPF_MOV64_IMM(BPF_REG_0, 1), 330 BPF_EXIT_INSN(), 331 BPF_MOV32_IMM(BPF_REG_2, 0), 332 BPF_MOV32_IMM(BPF_REG_3, 1), 333 BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2), 334 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 335 offsetof(struct __sk_buff, data)), 336 BPF_EXIT_INSN(), 337 }, 338 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 339 .result = ACCEPT, 340 .retval = 1, 341 }, 342 { 343 "calls: multiple ret types in subprog 1", 344 .insns = { 345 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 346 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 347 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 348 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 349 offsetof(struct __sk_buff, data_end)), 350 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 351 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 352 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 353 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 354 BPF_MOV64_IMM(BPF_REG_0, 1), 355 BPF_EXIT_INSN(), 356 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 357 offsetof(struct __sk_buff, data)), 358 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 359 BPF_MOV32_IMM(BPF_REG_0, 42), 360 BPF_EXIT_INSN(), 361 }, 362 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 363 .result = REJECT, 364 .errstr = "R0 invalid mem access 'scalar'", 365 }, 366 { 367 "calls: multiple ret types in subprog 2", 368 .insns = { 369 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 370 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 371 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 372 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 373 offsetof(struct __sk_buff, data_end)), 374 BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 375 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 376 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 377 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 378 BPF_MOV64_IMM(BPF_REG_0, 1), 379 BPF_EXIT_INSN(), 380 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 381 offsetof(struct __sk_buff, data)), 382 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 383 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9), 384 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 385 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 386 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 387 BPF_LD_MAP_FD(BPF_REG_1, 0), 388 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 389 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 390 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 391 offsetof(struct __sk_buff, data)), 392 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64), 393 BPF_EXIT_INSN(), 394 }, 395 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 396 .fixup_map_hash_8b = { 16 }, 397 .result = REJECT, 398 .errstr = "R0 min value is outside of the allowed memory range", 399 }, 400 { 401 "calls: overlapping caller/callee", 402 .insns = { 403 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0), 404 BPF_MOV64_IMM(BPF_REG_0, 1), 405 BPF_EXIT_INSN(), 406 }, 407 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 408 .errstr = "last insn is not an exit or jmp", 409 .result = REJECT, 410 }, 411 { 412 "calls: wrong recursive calls", 413 .insns = { 414 BPF_JMP_IMM(BPF_JA, 0, 0, 4), 415 BPF_JMP_IMM(BPF_JA, 0, 0, 4), 416 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 417 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 418 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 419 BPF_MOV64_IMM(BPF_REG_0, 1), 420 BPF_EXIT_INSN(), 421 }, 422 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 423 .errstr = "jump out of range", 424 .result = REJECT, 425 }, 426 { 427 "calls: wrong src reg", 428 .insns = { 429 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 3, 0, 0), 430 BPF_MOV64_IMM(BPF_REG_0, 1), 431 BPF_EXIT_INSN(), 432 }, 433 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 434 .errstr = "BPF_CALL uses reserved fields", 435 .result = REJECT, 436 }, 437 { 438 "calls: wrong off value", 439 .insns = { 440 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2), 441 BPF_MOV64_IMM(BPF_REG_0, 1), 442 BPF_EXIT_INSN(), 443 BPF_MOV64_IMM(BPF_REG_0, 2), 444 BPF_EXIT_INSN(), 445 }, 446 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 447 .errstr = "BPF_CALL uses reserved fields", 448 .result = REJECT, 449 }, 450 { 451 "calls: jump back loop", 452 .insns = { 453 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1), 454 BPF_MOV64_IMM(BPF_REG_0, 1), 455 BPF_EXIT_INSN(), 456 }, 457 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 458 .errstr = "recursive call", 459 .result = REJECT, 460 }, 461 { 462 "calls: conditional call", 463 .insns = { 464 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 465 offsetof(struct __sk_buff, mark)), 466 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 467 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 468 BPF_MOV64_IMM(BPF_REG_0, 1), 469 BPF_EXIT_INSN(), 470 BPF_MOV64_IMM(BPF_REG_0, 2), 471 BPF_EXIT_INSN(), 472 }, 473 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 474 .errstr = "jump out of range", 475 .result = REJECT, 476 }, 477 { 478 "calls: conditional call 2", 479 .insns = { 480 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 481 offsetof(struct __sk_buff, mark)), 482 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 483 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 484 BPF_MOV64_IMM(BPF_REG_0, 1), 485 BPF_EXIT_INSN(), 486 BPF_MOV64_IMM(BPF_REG_0, 2), 487 BPF_EXIT_INSN(), 488 BPF_MOV64_IMM(BPF_REG_0, 3), 489 BPF_EXIT_INSN(), 490 }, 491 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 492 .result = ACCEPT, 493 }, 494 { 495 "calls: conditional call 3", 496 .insns = { 497 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 498 offsetof(struct __sk_buff, mark)), 499 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 500 BPF_JMP_IMM(BPF_JA, 0, 0, 4), 501 BPF_MOV64_IMM(BPF_REG_0, 1), 502 BPF_EXIT_INSN(), 503 BPF_MOV64_IMM(BPF_REG_0, 1), 504 BPF_JMP_IMM(BPF_JA, 0, 0, -6), 505 BPF_MOV64_IMM(BPF_REG_0, 3), 506 BPF_JMP_IMM(BPF_JA, 0, 0, -6), 507 }, 508 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 509 .errstr_unpriv = "back-edge from insn", 510 .result_unpriv = REJECT, 511 .result = ACCEPT, 512 .retval = 1, 513 }, 514 { 515 "calls: conditional call 4", 516 .insns = { 517 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 518 offsetof(struct __sk_buff, mark)), 519 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 520 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 521 BPF_MOV64_IMM(BPF_REG_0, 1), 522 BPF_EXIT_INSN(), 523 BPF_MOV64_IMM(BPF_REG_0, 1), 524 BPF_JMP_IMM(BPF_JA, 0, 0, -5), 525 BPF_MOV64_IMM(BPF_REG_0, 3), 526 BPF_EXIT_INSN(), 527 }, 528 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 529 .result = ACCEPT, 530 }, 531 { 532 "calls: conditional call 5", 533 .insns = { 534 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 535 offsetof(struct __sk_buff, mark)), 536 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 537 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 538 BPF_MOV64_IMM(BPF_REG_0, 1), 539 BPF_EXIT_INSN(), 540 BPF_MOV64_IMM(BPF_REG_0, 1), 541 BPF_JMP_IMM(BPF_JA, 0, 0, -6), 542 BPF_MOV64_IMM(BPF_REG_0, 3), 543 BPF_EXIT_INSN(), 544 }, 545 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 546 .result = ACCEPT, 547 .retval = 1, 548 }, 549 { 550 "calls: conditional call 6", 551 .insns = { 552 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 553 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 554 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 555 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3), 556 BPF_EXIT_INSN(), 557 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 558 offsetof(struct __sk_buff, mark)), 559 BPF_EXIT_INSN(), 560 }, 561 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 562 .errstr = "infinite loop detected", 563 .result = REJECT, 564 }, 565 { 566 "calls: using r0 returned by callee", 567 .insns = { 568 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 569 BPF_EXIT_INSN(), 570 BPF_MOV64_IMM(BPF_REG_0, 2), 571 BPF_EXIT_INSN(), 572 }, 573 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 574 .result = ACCEPT, 575 }, 576 { 577 "calls: using uninit r0 from callee", 578 .insns = { 579 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 580 BPF_EXIT_INSN(), 581 BPF_EXIT_INSN(), 582 }, 583 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 584 .errstr = "!read_ok", 585 .result = REJECT, 586 }, 587 { 588 "calls: callee is using r1", 589 .insns = { 590 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 591 BPF_EXIT_INSN(), 592 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 593 offsetof(struct __sk_buff, len)), 594 BPF_EXIT_INSN(), 595 }, 596 .prog_type = BPF_PROG_TYPE_SCHED_ACT, 597 .result = ACCEPT, 598 .retval = TEST_DATA_LEN, 599 }, 600 { 601 "calls: callee using args1", 602 .insns = { 603 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 604 BPF_EXIT_INSN(), 605 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 606 BPF_EXIT_INSN(), 607 }, 608 .errstr_unpriv = "allowed for", 609 .result_unpriv = REJECT, 610 .result = ACCEPT, 611 .retval = POINTER_VALUE, 612 }, 613 { 614 "calls: callee using wrong args2", 615 .insns = { 616 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 617 BPF_EXIT_INSN(), 618 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 619 BPF_EXIT_INSN(), 620 }, 621 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 622 .errstr = "R2 !read_ok", 623 .result = REJECT, 624 }, 625 { 626 "calls: callee using two args", 627 .insns = { 628 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 629 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, 630 offsetof(struct __sk_buff, len)), 631 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, 632 offsetof(struct __sk_buff, len)), 633 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 634 BPF_EXIT_INSN(), 635 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 636 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 637 BPF_EXIT_INSN(), 638 }, 639 .errstr_unpriv = "allowed for", 640 .result_unpriv = REJECT, 641 .result = ACCEPT, 642 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN, 643 }, 644 { 645 "calls: callee changing pkt pointers", 646 .insns = { 647 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct xdp_md, data)), 648 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 649 offsetof(struct xdp_md, data_end)), 650 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6), 651 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8), 652 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2), 653 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 654 /* clear_all_pkt_pointers() has to walk all frames 655 * to make sure that pkt pointers in the caller 656 * are cleared when callee is calling a helper that 657 * adjusts packet size 658 */ 659 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 660 BPF_MOV32_IMM(BPF_REG_0, 0), 661 BPF_EXIT_INSN(), 662 BPF_MOV64_IMM(BPF_REG_2, 0), 663 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_xdp_adjust_head), 664 BPF_EXIT_INSN(), 665 }, 666 .result = REJECT, 667 .errstr = "R6 invalid mem access 'scalar'", 668 .prog_type = BPF_PROG_TYPE_XDP, 669 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 670 }, 671 { 672 "calls: ptr null check in subprog", 673 .insns = { 674 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 675 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 676 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 677 BPF_LD_MAP_FD(BPF_REG_1, 0), 678 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 679 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 680 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 681 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 682 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 683 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), 684 BPF_EXIT_INSN(), 685 BPF_MOV64_IMM(BPF_REG_0, 0), 686 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 687 BPF_MOV64_IMM(BPF_REG_0, 1), 688 BPF_EXIT_INSN(), 689 }, 690 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 691 .fixup_map_hash_48b = { 3 }, 692 .result_unpriv = REJECT, 693 .result = ACCEPT, 694 .retval = 0, 695 }, 696 { 697 "calls: two calls with args", 698 .insns = { 699 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 700 BPF_EXIT_INSN(), 701 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 702 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 703 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 704 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 705 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 706 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 707 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 708 BPF_EXIT_INSN(), 709 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 710 offsetof(struct __sk_buff, len)), 711 BPF_EXIT_INSN(), 712 }, 713 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 714 .result = ACCEPT, 715 .retval = TEST_DATA_LEN + TEST_DATA_LEN, 716 }, 717 { 718 "calls: calls with stack arith", 719 .insns = { 720 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 721 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 722 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 723 BPF_EXIT_INSN(), 724 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 725 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 726 BPF_EXIT_INSN(), 727 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 728 BPF_MOV64_IMM(BPF_REG_0, 42), 729 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), 730 BPF_EXIT_INSN(), 731 }, 732 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 733 .result = ACCEPT, 734 .retval = 42, 735 }, 736 { 737 "calls: calls with misaligned stack access", 738 .insns = { 739 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 740 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63), 741 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 742 BPF_EXIT_INSN(), 743 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61), 744 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 745 BPF_EXIT_INSN(), 746 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63), 747 BPF_MOV64_IMM(BPF_REG_0, 42), 748 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), 749 BPF_EXIT_INSN(), 750 }, 751 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 752 .flags = F_LOAD_WITH_STRICT_ALIGNMENT, 753 .errstr = "misaligned stack access", 754 .result = REJECT, 755 }, 756 { 757 "calls: calls control flow, jump test", 758 .insns = { 759 BPF_MOV64_IMM(BPF_REG_0, 42), 760 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 761 BPF_MOV64_IMM(BPF_REG_0, 43), 762 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 763 BPF_JMP_IMM(BPF_JA, 0, 0, -3), 764 BPF_EXIT_INSN(), 765 }, 766 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 767 .result = ACCEPT, 768 .retval = 43, 769 }, 770 { 771 "calls: calls control flow, jump test 2", 772 .insns = { 773 BPF_MOV64_IMM(BPF_REG_0, 42), 774 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 775 BPF_MOV64_IMM(BPF_REG_0, 43), 776 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 777 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3), 778 BPF_EXIT_INSN(), 779 }, 780 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 781 .errstr = "jump out of range from insn 1 to 4", 782 .result = REJECT, 783 }, 784 { 785 "calls: two calls with bad jump", 786 .insns = { 787 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 788 BPF_EXIT_INSN(), 789 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 790 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 791 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 792 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 793 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 794 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 795 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 796 BPF_EXIT_INSN(), 797 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 798 offsetof(struct __sk_buff, len)), 799 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3), 800 BPF_EXIT_INSN(), 801 }, 802 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 803 .errstr = "jump out of range from insn 11 to 9", 804 .result = REJECT, 805 }, 806 { 807 "calls: recursive call. test1", 808 .insns = { 809 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 810 BPF_EXIT_INSN(), 811 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1), 812 BPF_EXIT_INSN(), 813 }, 814 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 815 .errstr = "recursive call", 816 .result = REJECT, 817 }, 818 { 819 "calls: recursive call. test2", 820 .insns = { 821 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 822 BPF_EXIT_INSN(), 823 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3), 824 BPF_EXIT_INSN(), 825 }, 826 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 827 .errstr = "recursive call", 828 .result = REJECT, 829 }, 830 { 831 "calls: unreachable code", 832 .insns = { 833 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 834 BPF_EXIT_INSN(), 835 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 836 BPF_EXIT_INSN(), 837 BPF_MOV64_IMM(BPF_REG_0, 0), 838 BPF_EXIT_INSN(), 839 BPF_MOV64_IMM(BPF_REG_0, 0), 840 BPF_EXIT_INSN(), 841 }, 842 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 843 .errstr = "unreachable insn 6", 844 .result = REJECT, 845 }, 846 { 847 "calls: invalid call", 848 .insns = { 849 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 850 BPF_EXIT_INSN(), 851 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4), 852 BPF_EXIT_INSN(), 853 }, 854 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 855 .errstr = "invalid destination", 856 .result = REJECT, 857 }, 858 { 859 "calls: invalid call 2", 860 .insns = { 861 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 862 BPF_EXIT_INSN(), 863 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff), 864 BPF_EXIT_INSN(), 865 }, 866 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 867 .errstr = "invalid destination", 868 .result = REJECT, 869 }, 870 { 871 "calls: jumping across function bodies. test1", 872 .insns = { 873 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 874 BPF_MOV64_IMM(BPF_REG_0, 0), 875 BPF_EXIT_INSN(), 876 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3), 877 BPF_EXIT_INSN(), 878 }, 879 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 880 .errstr = "jump out of range", 881 .result = REJECT, 882 }, 883 { 884 "calls: jumping across function bodies. test2", 885 .insns = { 886 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 887 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 888 BPF_MOV64_IMM(BPF_REG_0, 0), 889 BPF_EXIT_INSN(), 890 BPF_EXIT_INSN(), 891 }, 892 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 893 .errstr = "jump out of range", 894 .result = REJECT, 895 }, 896 { 897 "calls: call without exit", 898 .insns = { 899 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 900 BPF_EXIT_INSN(), 901 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 902 BPF_EXIT_INSN(), 903 BPF_MOV64_IMM(BPF_REG_0, 0), 904 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2), 905 }, 906 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 907 .errstr = "not an exit", 908 .result = REJECT, 909 }, 910 { 911 "calls: call into middle of ld_imm64", 912 .insns = { 913 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 914 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 915 BPF_MOV64_IMM(BPF_REG_0, 0), 916 BPF_EXIT_INSN(), 917 BPF_LD_IMM64(BPF_REG_0, 0), 918 BPF_EXIT_INSN(), 919 }, 920 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 921 .errstr = "last insn", 922 .result = REJECT, 923 }, 924 { 925 "calls: call into middle of other call", 926 .insns = { 927 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 928 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 929 BPF_MOV64_IMM(BPF_REG_0, 0), 930 BPF_EXIT_INSN(), 931 BPF_MOV64_IMM(BPF_REG_0, 0), 932 BPF_MOV64_IMM(BPF_REG_0, 0), 933 BPF_EXIT_INSN(), 934 }, 935 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 936 .errstr = "last insn", 937 .result = REJECT, 938 }, 939 { 940 "calls: subprog call with ld_abs in main prog", 941 .insns = { 942 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 943 BPF_LD_ABS(BPF_B, 0), 944 BPF_LD_ABS(BPF_H, 0), 945 BPF_LD_ABS(BPF_W, 0), 946 BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), 947 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 948 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 949 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7), 950 BPF_LD_ABS(BPF_B, 0), 951 BPF_LD_ABS(BPF_H, 0), 952 BPF_LD_ABS(BPF_W, 0), 953 BPF_EXIT_INSN(), 954 BPF_MOV64_IMM(BPF_REG_2, 1), 955 BPF_MOV64_IMM(BPF_REG_3, 2), 956 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push), 957 BPF_EXIT_INSN(), 958 }, 959 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 960 .result = ACCEPT, 961 }, 962 { 963 "calls: two calls with bad fallthrough", 964 .insns = { 965 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 966 BPF_EXIT_INSN(), 967 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 968 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 969 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 970 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 971 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 972 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 973 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 974 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0), 975 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 976 offsetof(struct __sk_buff, len)), 977 BPF_EXIT_INSN(), 978 }, 979 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 980 .errstr = "not an exit", 981 .result = REJECT, 982 }, 983 { 984 "calls: two calls with stack read", 985 .insns = { 986 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 987 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 988 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 989 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 990 BPF_EXIT_INSN(), 991 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 992 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 993 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 994 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 995 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 996 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 997 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 998 BPF_EXIT_INSN(), 999 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), 1000 BPF_EXIT_INSN(), 1001 }, 1002 .prog_type = BPF_PROG_TYPE_XDP, 1003 .result = ACCEPT, 1004 }, 1005 { 1006 "calls: two calls with stack write", 1007 .insns = { 1008 /* main prog */ 1009 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1010 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1011 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1012 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1014 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1015 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 1016 BPF_EXIT_INSN(), 1017 1018 /* subprog 1 */ 1019 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1020 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7), 1022 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), 1023 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1024 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1025 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0), 1026 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8), 1027 /* write into stack frame of main prog */ 1028 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1029 BPF_EXIT_INSN(), 1030 1031 /* subprog 2 */ 1032 /* read from stack frame of main prog */ 1033 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), 1034 BPF_EXIT_INSN(), 1035 }, 1036 .prog_type = BPF_PROG_TYPE_XDP, 1037 .result = ACCEPT, 1038 }, 1039 { 1040 "calls: stack overflow using two frames (pre-call access)", 1041 .insns = { 1042 /* prog 1 */ 1043 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1044 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), 1045 BPF_EXIT_INSN(), 1046 1047 /* prog 2 */ 1048 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1049 BPF_MOV64_IMM(BPF_REG_0, 0), 1050 BPF_EXIT_INSN(), 1051 }, 1052 .prog_type = BPF_PROG_TYPE_XDP, 1053 .errstr = "combined stack size", 1054 .result = REJECT, 1055 }, 1056 { 1057 "calls: stack overflow using two frames (post-call access)", 1058 .insns = { 1059 /* prog 1 */ 1060 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), 1061 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1062 BPF_EXIT_INSN(), 1063 1064 /* prog 2 */ 1065 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1066 BPF_MOV64_IMM(BPF_REG_0, 0), 1067 BPF_EXIT_INSN(), 1068 }, 1069 .prog_type = BPF_PROG_TYPE_XDP, 1070 .errstr = "combined stack size", 1071 .result = REJECT, 1072 }, 1073 { 1074 "calls: stack depth check using three frames. test1", 1075 .insns = { 1076 /* main */ 1077 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 1078 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */ 1079 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0), 1080 BPF_MOV64_IMM(BPF_REG_0, 0), 1081 BPF_EXIT_INSN(), 1082 /* A */ 1083 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 1084 BPF_EXIT_INSN(), 1085 /* B */ 1086 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */ 1087 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 1088 BPF_EXIT_INSN(), 1089 }, 1090 .prog_type = BPF_PROG_TYPE_XDP, 1091 /* stack_main=32, stack_A=256, stack_B=64 1092 * and max(main+A, main+A+B) < 512 1093 */ 1094 .result = VERBOSE_ACCEPT, 1095 .errstr = "stack depth max 352\t" 1096 "subprog 0 (<unknown>) main insns_self \t" 1097 " insns_total \t" 1098 " stack 32\t" 1099 "subprog 1 (<unknown>) static insns_self \t" 1100 " insns_total \t" 1101 " stack 256\t" 1102 "subprog 2 (<unknown>) static insns_self \t" 1103 " insns_total \t" 1104 " stack 64", 1105 }, 1106 { 1107 "calls: stack depth check using three frames. test2", 1108 .insns = { 1109 /* main */ 1110 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 1111 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */ 1112 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0), 1113 BPF_MOV64_IMM(BPF_REG_0, 0), 1114 BPF_EXIT_INSN(), 1115 /* A */ 1116 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 1117 BPF_EXIT_INSN(), 1118 /* B */ 1119 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */ 1120 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 1121 BPF_EXIT_INSN(), 1122 }, 1123 .prog_type = BPF_PROG_TYPE_XDP, 1124 /* stack_main=32, stack_A=64, stack_B=256 1125 * and max(main+A, main+A+B) < 512 1126 */ 1127 .result = ACCEPT, 1128 }, 1129 { 1130 "calls: stack depth check using three frames. test3", 1131 .insns = { 1132 /* main */ 1133 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1134 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 1135 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1136 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */ 1137 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1), 1138 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 1139 BPF_MOV64_IMM(BPF_REG_0, 0), 1140 BPF_EXIT_INSN(), 1141 /* A */ 1142 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1), 1143 BPF_EXIT_INSN(), 1144 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0), 1145 BPF_JMP_IMM(BPF_JA, 0, 0, -3), 1146 /* B */ 1147 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1), 1148 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */ 1149 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 1150 BPF_EXIT_INSN(), 1151 }, 1152 .prog_type = BPF_PROG_TYPE_XDP, 1153 /* stack_main=64, stack_A=224, stack_B=256 1154 * and max(main+A, main+A+B) > 512 1155 */ 1156 .errstr = "combined stack", 1157 .result = REJECT, 1158 }, 1159 { 1160 "calls: stack depth check using three frames. test4", 1161 /* void main(void) { 1162 * func1(0); 1163 * func1(1); 1164 * func2(1); 1165 * } 1166 * void func1(int alloc_or_recurse) { 1167 * if (alloc_or_recurse) { 1168 * frame_pointer[-300] = 1; 1169 * } else { 1170 * func2(alloc_or_recurse); 1171 * } 1172 * } 1173 * void func2(int alloc_or_recurse) { 1174 * if (alloc_or_recurse) { 1175 * frame_pointer[-300] = 1; 1176 * } 1177 * } 1178 */ 1179 .insns = { 1180 /* main */ 1181 BPF_MOV64_IMM(BPF_REG_1, 0), 1182 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 1183 BPF_MOV64_IMM(BPF_REG_1, 1), 1184 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 1185 BPF_MOV64_IMM(BPF_REG_1, 1), 1186 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */ 1187 BPF_MOV64_IMM(BPF_REG_0, 0), 1188 BPF_EXIT_INSN(), 1189 /* A */ 1190 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2), 1191 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1192 BPF_EXIT_INSN(), 1193 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 1194 BPF_EXIT_INSN(), 1195 /* B */ 1196 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1197 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1198 BPF_EXIT_INSN(), 1199 }, 1200 .prog_type = BPF_PROG_TYPE_XDP, 1201 .result = REJECT, 1202 .errstr = "combined stack", 1203 }, 1204 { 1205 "calls: stack depth check using three frames. test5", 1206 .insns = { 1207 /* main */ 1208 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 1209 BPF_EXIT_INSN(), 1210 /* A */ 1211 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 1212 BPF_EXIT_INSN(), 1213 /* B */ 1214 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 1215 BPF_EXIT_INSN(), 1216 /* C */ 1217 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 1218 BPF_EXIT_INSN(), 1219 /* D */ 1220 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 1221 BPF_EXIT_INSN(), 1222 /* E */ 1223 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 1224 BPF_EXIT_INSN(), 1225 /* F */ 1226 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 1227 BPF_EXIT_INSN(), 1228 /* G */ 1229 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 1230 BPF_EXIT_INSN(), 1231 /* H */ 1232 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call I */ 1233 BPF_EXIT_INSN(), 1234 /* I */ 1235 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call J */ 1236 BPF_EXIT_INSN(), 1237 /* J */ 1238 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call K */ 1239 BPF_EXIT_INSN(), 1240 /* K */ 1241 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call L */ 1242 BPF_EXIT_INSN(), 1243 /* L */ 1244 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call M */ 1245 BPF_EXIT_INSN(), 1246 /* M */ 1247 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call N */ 1248 BPF_EXIT_INSN(), 1249 /* N */ 1250 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call O */ 1251 BPF_EXIT_INSN(), 1252 /* O */ 1253 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call P */ 1254 BPF_EXIT_INSN(), 1255 /* P */ 1256 BPF_MOV64_IMM(BPF_REG_0, 0), 1257 BPF_EXIT_INSN(), 1258 }, 1259 .prog_type = BPF_PROG_TYPE_XDP, 1260 .errstr = "call stack", 1261 .result = REJECT, 1262 }, 1263 { 1264 "calls: stack depth check in dead code", 1265 .insns = { 1266 /* main */ 1267 BPF_MOV64_IMM(BPF_REG_1, 0), 1268 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 1269 BPF_EXIT_INSN(), 1270 /* A */ 1271 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1272 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */ 1273 BPF_MOV64_IMM(BPF_REG_0, 0), 1274 BPF_EXIT_INSN(), 1275 /* B */ 1276 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 1277 BPF_EXIT_INSN(), 1278 /* C */ 1279 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 1280 BPF_EXIT_INSN(), 1281 /* D */ 1282 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 1283 BPF_EXIT_INSN(), 1284 /* E */ 1285 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 1286 BPF_EXIT_INSN(), 1287 /* F */ 1288 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 1289 BPF_EXIT_INSN(), 1290 /* G */ 1291 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 1292 BPF_EXIT_INSN(), 1293 /* H */ 1294 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call I */ 1295 BPF_EXIT_INSN(), 1296 /* I */ 1297 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call J */ 1298 BPF_EXIT_INSN(), 1299 /* J */ 1300 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call K */ 1301 BPF_EXIT_INSN(), 1302 /* K */ 1303 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call L */ 1304 BPF_EXIT_INSN(), 1305 /* L */ 1306 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call M */ 1307 BPF_EXIT_INSN(), 1308 /* M */ 1309 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call N */ 1310 BPF_EXIT_INSN(), 1311 /* N */ 1312 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call O */ 1313 BPF_EXIT_INSN(), 1314 /* O */ 1315 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call P */ 1316 BPF_EXIT_INSN(), 1317 /* P */ 1318 BPF_MOV64_IMM(BPF_REG_0, 0), 1319 BPF_EXIT_INSN(), 1320 }, 1321 .prog_type = BPF_PROG_TYPE_XDP, 1322 .errstr = "call stack", 1323 .result = REJECT, 1324 }, 1325 { 1326 "calls: spill into caller stack frame", 1327 .insns = { 1328 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1329 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1330 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1331 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1332 BPF_EXIT_INSN(), 1333 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), 1334 BPF_MOV64_IMM(BPF_REG_0, 0), 1335 BPF_EXIT_INSN(), 1336 }, 1337 .prog_type = BPF_PROG_TYPE_XDP, 1338 .errstr = "cannot spill", 1339 .result = REJECT, 1340 }, 1341 { 1342 "calls: write into caller stack frame", 1343 .insns = { 1344 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1346 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1348 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1349 BPF_EXIT_INSN(), 1350 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42), 1351 BPF_MOV64_IMM(BPF_REG_0, 0), 1352 BPF_EXIT_INSN(), 1353 }, 1354 .prog_type = BPF_PROG_TYPE_XDP, 1355 .result = ACCEPT, 1356 .retval = 42, 1357 }, 1358 { 1359 "calls: write into callee stack frame", 1360 .insns = { 1361 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1362 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), 1363 BPF_EXIT_INSN(), 1364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), 1365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8), 1366 BPF_EXIT_INSN(), 1367 }, 1368 .prog_type = BPF_PROG_TYPE_XDP, 1369 .errstr = "cannot return stack pointer", 1370 .result = REJECT, 1371 }, 1372 { 1373 "calls: two calls with stack write and void return", 1374 .insns = { 1375 /* main prog */ 1376 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1377 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1378 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1379 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1380 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1381 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1382 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 1383 BPF_EXIT_INSN(), 1384 1385 /* subprog 1 */ 1386 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1387 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1388 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1389 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1390 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1391 BPF_EXIT_INSN(), 1392 1393 /* subprog 2 */ 1394 /* write into stack frame of main prog */ 1395 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 1396 BPF_EXIT_INSN(), /* void return */ 1397 }, 1398 .prog_type = BPF_PROG_TYPE_XDP, 1399 .result = ACCEPT, 1400 }, 1401 { 1402 "calls: ambiguous return value", 1403 .insns = { 1404 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1405 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 1406 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1407 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1408 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1409 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1410 BPF_EXIT_INSN(), 1411 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1412 BPF_MOV64_IMM(BPF_REG_0, 0), 1413 BPF_EXIT_INSN(), 1414 }, 1415 .errstr_unpriv = "allowed for", 1416 .result_unpriv = REJECT, 1417 .errstr = "R0 !read_ok", 1418 .result = REJECT, 1419 }, 1420 { 1421 "calls: two calls that return map_value", 1422 .insns = { 1423 /* main prog */ 1424 /* pass fp-16, fp-8 into a function */ 1425 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1426 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1427 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1428 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1429 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 1430 1431 /* fetch map_value_ptr from the stack of this function */ 1432 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 1433 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 1434 /* write into map value */ 1435 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1436 /* fetch second map_value_ptr from the stack */ 1437 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 1438 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 1439 /* write into map value */ 1440 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1441 BPF_MOV64_IMM(BPF_REG_0, 0), 1442 BPF_EXIT_INSN(), 1443 1444 /* subprog 1 */ 1445 /* call 3rd function twice */ 1446 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1447 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1448 /* first time with fp-8 */ 1449 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1450 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1451 /* second time with fp-16 */ 1452 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1453 BPF_EXIT_INSN(), 1454 1455 /* subprog 2 */ 1456 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1457 /* lookup from map */ 1458 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1459 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1460 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1461 BPF_LD_MAP_FD(BPF_REG_1, 0), 1462 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1463 /* write map_value_ptr into stack frame of main prog */ 1464 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1465 BPF_MOV64_IMM(BPF_REG_0, 0), 1466 BPF_EXIT_INSN(), /* return 0 */ 1467 }, 1468 .prog_type = BPF_PROG_TYPE_XDP, 1469 .fixup_map_hash_8b = { 23 }, 1470 .result = ACCEPT, 1471 }, 1472 { 1473 "calls: two calls that return map_value with bool condition", 1474 .insns = { 1475 /* main prog */ 1476 /* pass fp-16, fp-8 into a function */ 1477 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1479 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1480 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1481 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1482 BPF_MOV64_IMM(BPF_REG_0, 0), 1483 BPF_EXIT_INSN(), 1484 1485 /* subprog 1 */ 1486 /* call 3rd function twice */ 1487 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1488 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1489 /* first time with fp-8 */ 1490 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 1491 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1492 /* fetch map_value_ptr from the stack of this function */ 1493 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1494 /* write into map value */ 1495 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1496 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1497 /* second time with fp-16 */ 1498 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1499 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1500 /* fetch second map_value_ptr from the stack */ 1501 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 1502 /* write into map value */ 1503 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1504 BPF_EXIT_INSN(), 1505 1506 /* subprog 2 */ 1507 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1508 /* lookup from map */ 1509 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1510 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1511 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1512 BPF_LD_MAP_FD(BPF_REG_1, 0), 1513 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1514 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1515 BPF_MOV64_IMM(BPF_REG_0, 0), 1516 BPF_EXIT_INSN(), /* return 0 */ 1517 /* write map_value_ptr into stack frame of main prog */ 1518 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1519 BPF_MOV64_IMM(BPF_REG_0, 1), 1520 BPF_EXIT_INSN(), /* return 1 */ 1521 }, 1522 .prog_type = BPF_PROG_TYPE_XDP, 1523 .fixup_map_hash_8b = { 23 }, 1524 .result = ACCEPT, 1525 }, 1526 { 1527 "calls: two calls that return map_value with incorrect bool check", 1528 .insns = { 1529 /* main prog */ 1530 /* pass fp-16, fp-8 into a function */ 1531 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1533 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1534 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1535 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1536 BPF_MOV64_IMM(BPF_REG_0, 0), 1537 BPF_EXIT_INSN(), 1538 1539 /* subprog 1 */ 1540 /* call 3rd function twice */ 1541 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1542 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1543 /* first time with fp-8 */ 1544 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 1545 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1546 /* fetch map_value_ptr from the stack of this function */ 1547 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1548 /* write into map value */ 1549 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1550 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1551 /* second time with fp-16 */ 1552 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1553 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1554 /* fetch second map_value_ptr from the stack */ 1555 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 1556 /* write into map value */ 1557 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1558 BPF_EXIT_INSN(), 1559 1560 /* subprog 2 */ 1561 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1562 /* lookup from map */ 1563 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1564 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1565 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1566 BPF_LD_MAP_FD(BPF_REG_1, 0), 1567 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1568 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1569 BPF_MOV64_IMM(BPF_REG_0, 0), 1570 BPF_EXIT_INSN(), /* return 0 */ 1571 /* write map_value_ptr into stack frame of main prog */ 1572 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1573 BPF_MOV64_IMM(BPF_REG_0, 1), 1574 BPF_EXIT_INSN(), /* return 1 */ 1575 }, 1576 .prog_type = BPF_PROG_TYPE_XDP, 1577 .fixup_map_hash_8b = { 23 }, 1578 .result = REJECT, 1579 .errstr = "R0 invalid mem access 'scalar'", 1580 .result_unpriv = REJECT, 1581 .errstr_unpriv = "invalid read from stack R7 off=-16 size=8", 1582 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1583 }, 1584 { 1585 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1", 1586 .insns = { 1587 /* main prog */ 1588 /* pass fp-16, fp-8 into a function */ 1589 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1590 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1591 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1592 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1593 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1594 BPF_MOV64_IMM(BPF_REG_0, 0), 1595 BPF_EXIT_INSN(), 1596 1597 /* subprog 1 */ 1598 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1599 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1600 /* 1st lookup from map */ 1601 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1602 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1603 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1604 BPF_LD_MAP_FD(BPF_REG_1, 0), 1605 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1606 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1607 BPF_MOV64_IMM(BPF_REG_8, 0), 1608 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1609 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1610 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1611 BPF_MOV64_IMM(BPF_REG_8, 1), 1612 1613 /* 2nd lookup from map */ 1614 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 1615 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1616 BPF_LD_MAP_FD(BPF_REG_1, 0), 1617 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 1618 BPF_FUNC_map_lookup_elem), 1619 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1620 BPF_MOV64_IMM(BPF_REG_9, 0), 1621 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1622 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1623 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1624 BPF_MOV64_IMM(BPF_REG_9, 1), 1625 1626 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1627 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 1628 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1629 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1630 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1631 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 1632 BPF_EXIT_INSN(), 1633 1634 /* subprog 2 */ 1635 /* if arg2 == 1 do *arg1 = 0 */ 1636 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1637 /* fetch map_value_ptr from the stack of this function */ 1638 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1639 /* write into map value */ 1640 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1641 1642 /* if arg4 == 1 do *arg3 = 0 */ 1643 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1644 /* fetch map_value_ptr from the stack of this function */ 1645 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1646 /* write into map value */ 1647 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 1648 BPF_EXIT_INSN(), 1649 }, 1650 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1651 .fixup_map_hash_8b = { 12, 22 }, 1652 .result = REJECT, 1653 .errstr = "invalid access to map value, value_size=8 off=2 size=8", 1654 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1655 }, 1656 { 1657 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2", 1658 .insns = { 1659 /* main prog */ 1660 /* pass fp-16, fp-8 into a function */ 1661 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1662 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1663 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1664 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1665 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1666 BPF_MOV64_IMM(BPF_REG_0, 0), 1667 BPF_EXIT_INSN(), 1668 1669 /* subprog 1 */ 1670 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1671 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1672 /* 1st lookup from map */ 1673 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1674 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1675 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1676 BPF_LD_MAP_FD(BPF_REG_1, 0), 1677 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1678 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1679 BPF_MOV64_IMM(BPF_REG_8, 0), 1680 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1681 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1682 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1683 BPF_MOV64_IMM(BPF_REG_8, 1), 1684 1685 /* 2nd lookup from map */ 1686 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 1687 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1688 BPF_LD_MAP_FD(BPF_REG_1, 0), 1689 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 1690 BPF_FUNC_map_lookup_elem), 1691 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1692 BPF_MOV64_IMM(BPF_REG_9, 0), 1693 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1694 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1695 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1696 BPF_MOV64_IMM(BPF_REG_9, 1), 1697 1698 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1699 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 1700 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1701 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1702 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 1704 BPF_EXIT_INSN(), 1705 1706 /* subprog 2 */ 1707 /* if arg2 == 1 do *arg1 = 0 */ 1708 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1709 /* fetch map_value_ptr from the stack of this function */ 1710 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1711 /* write into map value */ 1712 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1713 1714 /* if arg4 == 1 do *arg3 = 0 */ 1715 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1716 /* fetch map_value_ptr from the stack of this function */ 1717 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1718 /* write into map value */ 1719 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1720 BPF_EXIT_INSN(), 1721 }, 1722 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1723 .fixup_map_hash_8b = { 12, 22 }, 1724 .result = ACCEPT, 1725 }, 1726 { 1727 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3", 1728 .insns = { 1729 /* main prog */ 1730 /* pass fp-16, fp-8 into a function */ 1731 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1732 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1733 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1734 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1735 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), 1736 BPF_MOV64_IMM(BPF_REG_0, 0), 1737 BPF_EXIT_INSN(), 1738 1739 /* subprog 1 */ 1740 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1741 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1742 /* 1st lookup from map */ 1743 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0), 1744 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1745 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 1746 BPF_LD_MAP_FD(BPF_REG_1, 0), 1747 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1748 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1749 BPF_MOV64_IMM(BPF_REG_8, 0), 1750 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1751 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1752 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1753 BPF_MOV64_IMM(BPF_REG_8, 1), 1754 1755 /* 2nd lookup from map */ 1756 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1757 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 1758 BPF_LD_MAP_FD(BPF_REG_1, 0), 1759 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1760 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1761 BPF_MOV64_IMM(BPF_REG_9, 0), // 26 1762 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1763 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1764 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1765 BPF_MOV64_IMM(BPF_REG_9, 1), 1766 1767 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1768 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30 1769 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1770 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1771 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1772 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34 1773 BPF_JMP_IMM(BPF_JA, 0, 0, -30), 1774 1775 /* subprog 2 */ 1776 /* if arg2 == 1 do *arg1 = 0 */ 1777 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1778 /* fetch map_value_ptr from the stack of this function */ 1779 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1780 /* write into map value */ 1781 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1782 1783 /* if arg4 == 1 do *arg3 = 0 */ 1784 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1785 /* fetch map_value_ptr from the stack of this function */ 1786 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1787 /* write into map value */ 1788 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 1789 BPF_JMP_IMM(BPF_JA, 0, 0, -8), 1790 }, 1791 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1792 .fixup_map_hash_8b = { 12, 22 }, 1793 .result = REJECT, 1794 .errstr = "invalid access to map value, value_size=8 off=2 size=8", 1795 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1796 }, 1797 { 1798 "calls: two calls that receive map_value_ptr_or_null via arg. test1", 1799 .insns = { 1800 /* main prog */ 1801 /* pass fp-16, fp-8 into a function */ 1802 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1803 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1804 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1805 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1806 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1807 BPF_MOV64_IMM(BPF_REG_0, 0), 1808 BPF_EXIT_INSN(), 1809 1810 /* subprog 1 */ 1811 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1812 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1813 /* 1st lookup from map */ 1814 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1815 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1816 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1817 BPF_LD_MAP_FD(BPF_REG_1, 0), 1818 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1819 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 1820 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1821 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1822 BPF_MOV64_IMM(BPF_REG_8, 0), 1823 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1824 BPF_MOV64_IMM(BPF_REG_8, 1), 1825 1826 /* 2nd lookup from map */ 1827 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1828 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1829 BPF_LD_MAP_FD(BPF_REG_1, 0), 1830 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1831 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 1832 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1833 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1834 BPF_MOV64_IMM(BPF_REG_9, 0), 1835 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1836 BPF_MOV64_IMM(BPF_REG_9, 1), 1837 1838 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1839 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1840 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1841 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1842 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1843 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1844 BPF_EXIT_INSN(), 1845 1846 /* subprog 2 */ 1847 /* if arg2 == 1 do *arg1 = 0 */ 1848 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1849 /* fetch map_value_ptr from the stack of this function */ 1850 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1851 /* write into map value */ 1852 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1853 1854 /* if arg4 == 1 do *arg3 = 0 */ 1855 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1856 /* fetch map_value_ptr from the stack of this function */ 1857 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1858 /* write into map value */ 1859 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1860 BPF_EXIT_INSN(), 1861 }, 1862 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1863 .fixup_map_hash_8b = { 12, 22 }, 1864 .result = ACCEPT, 1865 }, 1866 { 1867 "calls: two calls that receive map_value_ptr_or_null via arg. test2", 1868 .insns = { 1869 /* main prog */ 1870 /* pass fp-16, fp-8 into a function */ 1871 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1872 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1873 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1874 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1875 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1876 BPF_MOV64_IMM(BPF_REG_0, 0), 1877 BPF_EXIT_INSN(), 1878 1879 /* subprog 1 */ 1880 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1881 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1882 /* 1st lookup from map */ 1883 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1884 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1885 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1886 BPF_LD_MAP_FD(BPF_REG_1, 0), 1887 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1888 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 1889 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1890 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1891 BPF_MOV64_IMM(BPF_REG_8, 0), 1892 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1893 BPF_MOV64_IMM(BPF_REG_8, 1), 1894 1895 /* 2nd lookup from map */ 1896 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1898 BPF_LD_MAP_FD(BPF_REG_1, 0), 1899 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1900 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 1901 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1902 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1903 BPF_MOV64_IMM(BPF_REG_9, 0), 1904 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1905 BPF_MOV64_IMM(BPF_REG_9, 1), 1906 1907 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1908 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1909 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1910 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1911 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1912 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1913 BPF_EXIT_INSN(), 1914 1915 /* subprog 2 */ 1916 /* if arg2 == 1 do *arg1 = 0 */ 1917 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1918 /* fetch map_value_ptr from the stack of this function */ 1919 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1920 /* write into map value */ 1921 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1922 1923 /* if arg4 == 0 do *arg3 = 0 */ 1924 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2), 1925 /* fetch map_value_ptr from the stack of this function */ 1926 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1927 /* write into map value */ 1928 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1929 BPF_EXIT_INSN(), 1930 }, 1931 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1932 .fixup_map_hash_8b = { 12, 22 }, 1933 .result = REJECT, 1934 .errstr = "R0 invalid mem access 'scalar'", 1935 }, 1936 { 1937 "calls: pkt_ptr spill into caller stack", 1938 .insns = { 1939 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 1940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 1941 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1942 BPF_EXIT_INSN(), 1943 1944 /* subprog 1 */ 1945 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1946 offsetof(struct __sk_buff, data)), 1947 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1948 offsetof(struct __sk_buff, data_end)), 1949 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1950 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1951 /* spill unchecked pkt_ptr into stack of caller */ 1952 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 1953 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 1954 /* now the pkt range is verified, read pkt_ptr from stack */ 1955 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 1956 /* write 4 bytes into packet */ 1957 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 1958 BPF_EXIT_INSN(), 1959 }, 1960 .result = ACCEPT, 1961 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1962 .retval = POINTER_VALUE, 1963 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1964 }, 1965 { 1966 "calls: pkt_ptr spill into caller stack 2", 1967 .insns = { 1968 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 1969 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 1970 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1971 /* Marking is still kept, but not in all cases safe. */ 1972 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 1973 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 1974 BPF_EXIT_INSN(), 1975 1976 /* subprog 1 */ 1977 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1978 offsetof(struct __sk_buff, data)), 1979 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1980 offsetof(struct __sk_buff, data_end)), 1981 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1982 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1983 /* spill unchecked pkt_ptr into stack of caller */ 1984 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 1985 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 1986 /* now the pkt range is verified, read pkt_ptr from stack */ 1987 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 1988 /* write 4 bytes into packet */ 1989 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 1990 BPF_EXIT_INSN(), 1991 }, 1992 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1993 .errstr = "invalid access to packet", 1994 .result = REJECT, 1995 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1996 }, 1997 { 1998 "calls: pkt_ptr spill into caller stack 3", 1999 .insns = { 2000 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2001 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2002 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2003 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 2004 /* Marking is still kept and safe here. */ 2005 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2006 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 2007 BPF_EXIT_INSN(), 2008 2009 /* subprog 1 */ 2010 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2011 offsetof(struct __sk_buff, data)), 2012 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2013 offsetof(struct __sk_buff, data_end)), 2014 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2015 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2016 /* spill unchecked pkt_ptr into stack of caller */ 2017 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2018 BPF_MOV64_IMM(BPF_REG_5, 0), 2019 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2020 BPF_MOV64_IMM(BPF_REG_5, 1), 2021 /* now the pkt range is verified, read pkt_ptr from stack */ 2022 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 2023 /* write 4 bytes into packet */ 2024 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2025 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2026 BPF_EXIT_INSN(), 2027 }, 2028 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2029 .result = ACCEPT, 2030 .retval = 1, 2031 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2032 }, 2033 { 2034 "calls: pkt_ptr spill into caller stack 4", 2035 .insns = { 2036 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2037 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2038 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2039 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 2040 /* Check marking propagated. */ 2041 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2042 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 2043 BPF_EXIT_INSN(), 2044 2045 /* subprog 1 */ 2046 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2047 offsetof(struct __sk_buff, data)), 2048 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2049 offsetof(struct __sk_buff, data_end)), 2050 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2052 /* spill unchecked pkt_ptr into stack of caller */ 2053 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2054 BPF_MOV64_IMM(BPF_REG_5, 0), 2055 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 2056 BPF_MOV64_IMM(BPF_REG_5, 1), 2057 /* don't read back pkt_ptr from stack here */ 2058 /* write 4 bytes into packet */ 2059 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2060 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2061 BPF_EXIT_INSN(), 2062 }, 2063 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2064 .result = ACCEPT, 2065 .retval = 1, 2066 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2067 }, 2068 { 2069 "calls: pkt_ptr spill into caller stack 5", 2070 .insns = { 2071 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2072 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2073 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0), 2074 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2075 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2076 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2077 BPF_EXIT_INSN(), 2078 2079 /* subprog 1 */ 2080 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2081 offsetof(struct __sk_buff, data)), 2082 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2083 offsetof(struct __sk_buff, data_end)), 2084 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2085 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2086 BPF_MOV64_IMM(BPF_REG_5, 0), 2087 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2088 /* spill checked pkt_ptr into stack of caller */ 2089 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2090 BPF_MOV64_IMM(BPF_REG_5, 1), 2091 /* don't read back pkt_ptr from stack here */ 2092 /* write 4 bytes into packet */ 2093 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2094 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2095 BPF_EXIT_INSN(), 2096 }, 2097 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2098 .errstr = "same insn cannot be used with different", 2099 .result = REJECT, 2100 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2101 }, 2102 { 2103 "calls: pkt_ptr spill into caller stack 6", 2104 .insns = { 2105 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2106 offsetof(struct __sk_buff, data_end)), 2107 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2108 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2109 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2110 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2111 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2112 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2113 BPF_EXIT_INSN(), 2114 2115 /* subprog 1 */ 2116 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2117 offsetof(struct __sk_buff, data)), 2118 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2119 offsetof(struct __sk_buff, data_end)), 2120 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2121 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2122 BPF_MOV64_IMM(BPF_REG_5, 0), 2123 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2124 /* spill checked pkt_ptr into stack of caller */ 2125 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2126 BPF_MOV64_IMM(BPF_REG_5, 1), 2127 /* don't read back pkt_ptr from stack here */ 2128 /* write 4 bytes into packet */ 2129 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2130 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2131 BPF_EXIT_INSN(), 2132 }, 2133 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2134 .errstr = "R4 invalid mem access", 2135 .result = REJECT, 2136 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2137 }, 2138 { 2139 "calls: pkt_ptr spill into caller stack 7", 2140 .insns = { 2141 BPF_MOV64_IMM(BPF_REG_2, 0), 2142 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2143 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2144 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2145 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2146 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2147 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2148 BPF_EXIT_INSN(), 2149 2150 /* subprog 1 */ 2151 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2152 offsetof(struct __sk_buff, data)), 2153 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2154 offsetof(struct __sk_buff, data_end)), 2155 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2157 BPF_MOV64_IMM(BPF_REG_5, 0), 2158 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2159 /* spill checked pkt_ptr into stack of caller */ 2160 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2161 BPF_MOV64_IMM(BPF_REG_5, 1), 2162 /* don't read back pkt_ptr from stack here */ 2163 /* write 4 bytes into packet */ 2164 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2165 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2166 BPF_EXIT_INSN(), 2167 }, 2168 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2169 .errstr = "R4 invalid mem access", 2170 .result = REJECT, 2171 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2172 }, 2173 { 2174 "calls: pkt_ptr spill into caller stack 8", 2175 .insns = { 2176 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2177 offsetof(struct __sk_buff, data)), 2178 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2179 offsetof(struct __sk_buff, data_end)), 2180 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2181 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2182 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 2183 BPF_EXIT_INSN(), 2184 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2185 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2186 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2187 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2188 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2189 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2190 BPF_EXIT_INSN(), 2191 2192 /* subprog 1 */ 2193 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2194 offsetof(struct __sk_buff, data)), 2195 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2196 offsetof(struct __sk_buff, data_end)), 2197 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2198 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2199 BPF_MOV64_IMM(BPF_REG_5, 0), 2200 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2201 /* spill checked pkt_ptr into stack of caller */ 2202 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2203 BPF_MOV64_IMM(BPF_REG_5, 1), 2204 /* don't read back pkt_ptr from stack here */ 2205 /* write 4 bytes into packet */ 2206 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2207 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2208 BPF_EXIT_INSN(), 2209 }, 2210 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2211 .result = ACCEPT, 2212 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2213 }, 2214 { 2215 "calls: pkt_ptr spill into caller stack 9", 2216 .insns = { 2217 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2218 offsetof(struct __sk_buff, data)), 2219 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2220 offsetof(struct __sk_buff, data_end)), 2221 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2222 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2223 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 2224 BPF_EXIT_INSN(), 2225 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2226 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2227 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2228 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2229 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2230 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2231 BPF_EXIT_INSN(), 2232 2233 /* subprog 1 */ 2234 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2235 offsetof(struct __sk_buff, data)), 2236 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2237 offsetof(struct __sk_buff, data_end)), 2238 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2239 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2240 BPF_MOV64_IMM(BPF_REG_5, 0), 2241 /* spill unchecked pkt_ptr into stack of caller */ 2242 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2243 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 2244 BPF_MOV64_IMM(BPF_REG_5, 1), 2245 /* don't read back pkt_ptr from stack here */ 2246 /* write 4 bytes into packet */ 2247 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2248 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2249 BPF_EXIT_INSN(), 2250 }, 2251 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2252 .errstr = "invalid access to packet", 2253 .result = REJECT, 2254 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2255 }, 2256 { 2257 "calls: caller stack init to zero or map_value_or_null", 2258 .insns = { 2259 BPF_MOV64_IMM(BPF_REG_0, 0), 2260 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 2261 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2262 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2263 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2264 /* fetch map_value_or_null or const_zero from stack */ 2265 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 2266 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2267 /* store into map_value */ 2268 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0), 2269 BPF_EXIT_INSN(), 2270 2271 /* subprog 1 */ 2272 /* if (ctx == 0) return; */ 2273 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8), 2274 /* else bpf_map_lookup() and *(fp - 8) = r0 */ 2275 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 2276 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2278 BPF_LD_MAP_FD(BPF_REG_1, 0), 2279 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2280 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 2281 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 2282 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 2283 BPF_EXIT_INSN(), 2284 }, 2285 .fixup_map_hash_8b = { 13 }, 2286 .result = ACCEPT, 2287 .prog_type = BPF_PROG_TYPE_XDP, 2288 }, 2289 { 2290 "calls: stack init to zero and pruning", 2291 .insns = { 2292 /* first make allocated_stack 16 byte */ 2293 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 2294 /* now fork the execution such that the false branch 2295 * of JGT insn will be verified second and it skisp zero 2296 * init of fp-8 stack slot. If stack liveness marking 2297 * is missing live_read marks from call map_lookup 2298 * processing then pruning will incorrectly assume 2299 * that fp-8 stack slot was unused in the fall-through 2300 * branch and will accept the program incorrectly 2301 */ 2302 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), 2303 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2), 2304 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2305 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 2306 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2308 BPF_LD_MAP_FD(BPF_REG_1, 0), 2309 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 2310 BPF_MOV64_IMM(BPF_REG_0, 0), 2311 BPF_EXIT_INSN(), 2312 }, 2313 .fixup_map_hash_48b = { 7 }, 2314 .errstr_unpriv = "invalid read from stack R2 off -8+0 size 8", 2315 .result_unpriv = REJECT, 2316 /* in privileged mode reads from uninitialized stack locations are permitted */ 2317 .result = ACCEPT, 2318 }, 2319 { 2320 "calls: ctx read at start of subprog", 2321 .insns = { 2322 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 2323 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 2324 BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0), 2325 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2326 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 2327 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2328 BPF_EXIT_INSN(), 2329 BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 2330 BPF_MOV64_IMM(BPF_REG_0, 0), 2331 BPF_EXIT_INSN(), 2332 }, 2333 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2334 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2335 .result_unpriv = REJECT, 2336 .result = ACCEPT, 2337 }, 2338 { 2339 "calls: cross frame pruning", 2340 .insns = { 2341 /* r8 = !!random(); 2342 * call pruner() 2343 * if (r8) 2344 * do something bad; 2345 */ 2346 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2347 BPF_MOV64_IMM(BPF_REG_8, 0), 2348 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2349 BPF_MOV64_IMM(BPF_REG_8, 1), 2350 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), 2351 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2352 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 2353 BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 2354 BPF_MOV64_IMM(BPF_REG_0, 0), 2355 BPF_EXIT_INSN(), 2356 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 2357 BPF_EXIT_INSN(), 2358 }, 2359 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2360 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2361 .errstr = "!read_ok", 2362 .result = REJECT, 2363 }, 2364 { 2365 "calls: cross frame pruning - liveness propagation", 2366 .insns = { 2367 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2368 BPF_MOV64_IMM(BPF_REG_8, 0), 2369 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2370 BPF_MOV64_IMM(BPF_REG_8, 1), 2371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2372 BPF_MOV64_IMM(BPF_REG_9, 0), 2373 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2374 BPF_MOV64_IMM(BPF_REG_9, 1), 2375 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2376 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2377 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 2378 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0), 2379 BPF_MOV64_IMM(BPF_REG_0, 0), 2380 BPF_EXIT_INSN(), 2381 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 2382 BPF_EXIT_INSN(), 2383 }, 2384 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2385 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2386 .errstr = "!read_ok", 2387 .result = REJECT, 2388 }, 2389 /* Make sure that verifier.c:states_equal() considers IDs from all 2390 * frames when building 'idmap' for check_ids(). 2391 */ 2392 { 2393 "calls: check_ids() across call boundary", 2394 .insns = { 2395 /* Function main() */ 2396 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2397 /* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 2398 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2400 BPF_LD_MAP_FD(BPF_REG_1, 2401 0), 2402 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 2403 BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24), 2404 /* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 2405 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2406 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2407 BPF_LD_MAP_FD(BPF_REG_1, 2408 0), 2409 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 2410 BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32), 2411 /* call foo(&fp[-24], &fp[-32]) ; both arguments have IDs in the current 2412 * ; stack frame 2413 */ 2414 BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP), 2415 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24), 2416 BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), 2417 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32), 2418 BPF_CALL_REL(2), 2419 /* exit 0 */ 2420 BPF_MOV64_IMM(BPF_REG_0, 0), 2421 BPF_EXIT_INSN(), 2422 /* Function foo() 2423 * 2424 * r9 = &frame[0].fp[-24] ; save arguments in the callee saved registers, 2425 * r8 = &frame[0].fp[-32] ; arguments are pointers to pointers to map value 2426 */ 2427 BPF_MOV64_REG(BPF_REG_9, BPF_REG_1), 2428 BPF_MOV64_REG(BPF_REG_8, BPF_REG_2), 2429 /* r7 = ktime_get_ns() */ 2430 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 2431 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 2432 /* r6 = ktime_get_ns() */ 2433 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 2434 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 2435 /* if r6 > r7 goto +1 ; no new information about the state is derived from 2436 * ; this check, thus produced verifier states differ 2437 * ; only in 'insn_idx' 2438 * r9 = r8 2439 */ 2440 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), 2441 BPF_MOV64_REG(BPF_REG_9, BPF_REG_8), 2442 /* r9 = *r9 ; verifier gets to this point via two paths: 2443 * ; (I) one including r9 = r8, verified first; 2444 * ; (II) one excluding r9 = r8, verified next. 2445 * ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id. 2446 * ; Suppose that checkpoint is created here via path (I). 2447 * ; When verifying via (II) the r9.id must be compared against 2448 * ; frame[0].fp[-24].id, otherwise (I) and (II) would be 2449 * ; incorrectly deemed equivalent. 2450 * if r9 == 0 goto <exit> 2451 */ 2452 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0), 2453 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1), 2454 /* r8 = *r8 ; read map value via r8, this is not safe 2455 * r0 = *r8 ; because r8 might be not equal to r9. 2456 */ 2457 BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0), 2458 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0), 2459 /* exit 0 */ 2460 BPF_MOV64_IMM(BPF_REG_0, 0), 2461 BPF_EXIT_INSN(), 2462 }, 2463 .flags = BPF_F_TEST_STATE_FREQ, 2464 .fixup_map_hash_8b = { 3, 9 }, 2465 .result = REJECT, 2466 .errstr = "R8 invalid mem access 'map_value_or_null'", 2467 .result_unpriv = REJECT, 2468 .errstr_unpriv = "", 2469 .prog_type = BPF_PROG_TYPE_CGROUP_SKB, 2470 }, 2471