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 pointer type STRUCT prog_test_fail1 must point to scalar", 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 pointer type 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 pointer type STRUCT prog_test_fail3 must point to scalar", 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 = ACCEPT, 1095 }, 1096 { 1097 "calls: stack depth check using three frames. test2", 1098 .insns = { 1099 /* main */ 1100 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 1101 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */ 1102 BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0), 1103 BPF_MOV64_IMM(BPF_REG_0, 0), 1104 BPF_EXIT_INSN(), 1105 /* A */ 1106 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 1107 BPF_EXIT_INSN(), 1108 /* B */ 1109 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */ 1110 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 1111 BPF_EXIT_INSN(), 1112 }, 1113 .prog_type = BPF_PROG_TYPE_XDP, 1114 /* stack_main=32, stack_A=64, stack_B=256 1115 * and max(main+A, main+A+B) < 512 1116 */ 1117 .result = ACCEPT, 1118 }, 1119 { 1120 "calls: stack depth check using three frames. test3", 1121 .insns = { 1122 /* main */ 1123 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1124 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 1125 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1126 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */ 1127 BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1), 1128 BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 1129 BPF_MOV64_IMM(BPF_REG_0, 0), 1130 BPF_EXIT_INSN(), 1131 /* A */ 1132 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1), 1133 BPF_EXIT_INSN(), 1134 BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0), 1135 BPF_JMP_IMM(BPF_JA, 0, 0, -3), 1136 /* B */ 1137 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1), 1138 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */ 1139 BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 1140 BPF_EXIT_INSN(), 1141 }, 1142 .prog_type = BPF_PROG_TYPE_XDP, 1143 /* stack_main=64, stack_A=224, stack_B=256 1144 * and max(main+A, main+A+B) > 512 1145 */ 1146 .errstr = "combined stack", 1147 .result = REJECT, 1148 }, 1149 { 1150 "calls: stack depth check using three frames. test4", 1151 /* void main(void) { 1152 * func1(0); 1153 * func1(1); 1154 * func2(1); 1155 * } 1156 * void func1(int alloc_or_recurse) { 1157 * if (alloc_or_recurse) { 1158 * frame_pointer[-300] = 1; 1159 * } else { 1160 * func2(alloc_or_recurse); 1161 * } 1162 * } 1163 * void func2(int alloc_or_recurse) { 1164 * if (alloc_or_recurse) { 1165 * frame_pointer[-300] = 1; 1166 * } 1167 * } 1168 */ 1169 .insns = { 1170 /* main */ 1171 BPF_MOV64_IMM(BPF_REG_1, 0), 1172 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 1173 BPF_MOV64_IMM(BPF_REG_1, 1), 1174 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 1175 BPF_MOV64_IMM(BPF_REG_1, 1), 1176 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */ 1177 BPF_MOV64_IMM(BPF_REG_0, 0), 1178 BPF_EXIT_INSN(), 1179 /* A */ 1180 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2), 1181 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1182 BPF_EXIT_INSN(), 1183 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 1184 BPF_EXIT_INSN(), 1185 /* B */ 1186 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1187 BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 1188 BPF_EXIT_INSN(), 1189 }, 1190 .prog_type = BPF_PROG_TYPE_XDP, 1191 .result = REJECT, 1192 .errstr = "combined stack", 1193 }, 1194 { 1195 "calls: stack depth check using three frames. test5", 1196 .insns = { 1197 /* main */ 1198 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 1199 BPF_EXIT_INSN(), 1200 /* A */ 1201 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 1202 BPF_EXIT_INSN(), 1203 /* B */ 1204 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 1205 BPF_EXIT_INSN(), 1206 /* C */ 1207 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 1208 BPF_EXIT_INSN(), 1209 /* D */ 1210 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 1211 BPF_EXIT_INSN(), 1212 /* E */ 1213 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 1214 BPF_EXIT_INSN(), 1215 /* F */ 1216 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 1217 BPF_EXIT_INSN(), 1218 /* G */ 1219 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 1220 BPF_EXIT_INSN(), 1221 /* H */ 1222 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call I */ 1223 BPF_EXIT_INSN(), 1224 /* I */ 1225 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call J */ 1226 BPF_EXIT_INSN(), 1227 /* J */ 1228 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call K */ 1229 BPF_EXIT_INSN(), 1230 /* K */ 1231 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call L */ 1232 BPF_EXIT_INSN(), 1233 /* L */ 1234 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call M */ 1235 BPF_EXIT_INSN(), 1236 /* M */ 1237 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call N */ 1238 BPF_EXIT_INSN(), 1239 /* N */ 1240 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call O */ 1241 BPF_EXIT_INSN(), 1242 /* O */ 1243 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call P */ 1244 BPF_EXIT_INSN(), 1245 /* P */ 1246 BPF_MOV64_IMM(BPF_REG_0, 0), 1247 BPF_EXIT_INSN(), 1248 }, 1249 .prog_type = BPF_PROG_TYPE_XDP, 1250 .errstr = "call stack", 1251 .result = REJECT, 1252 }, 1253 { 1254 "calls: stack depth check in dead code", 1255 .insns = { 1256 /* main */ 1257 BPF_MOV64_IMM(BPF_REG_1, 0), 1258 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 1259 BPF_EXIT_INSN(), 1260 /* A */ 1261 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1262 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */ 1263 BPF_MOV64_IMM(BPF_REG_0, 0), 1264 BPF_EXIT_INSN(), 1265 /* B */ 1266 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 1267 BPF_EXIT_INSN(), 1268 /* C */ 1269 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 1270 BPF_EXIT_INSN(), 1271 /* D */ 1272 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 1273 BPF_EXIT_INSN(), 1274 /* E */ 1275 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 1276 BPF_EXIT_INSN(), 1277 /* F */ 1278 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 1279 BPF_EXIT_INSN(), 1280 /* G */ 1281 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 1282 BPF_EXIT_INSN(), 1283 /* H */ 1284 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call I */ 1285 BPF_EXIT_INSN(), 1286 /* I */ 1287 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call J */ 1288 BPF_EXIT_INSN(), 1289 /* J */ 1290 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call K */ 1291 BPF_EXIT_INSN(), 1292 /* K */ 1293 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call L */ 1294 BPF_EXIT_INSN(), 1295 /* L */ 1296 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call M */ 1297 BPF_EXIT_INSN(), 1298 /* M */ 1299 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call N */ 1300 BPF_EXIT_INSN(), 1301 /* N */ 1302 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call O */ 1303 BPF_EXIT_INSN(), 1304 /* O */ 1305 BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call P */ 1306 BPF_EXIT_INSN(), 1307 /* P */ 1308 BPF_MOV64_IMM(BPF_REG_0, 0), 1309 BPF_EXIT_INSN(), 1310 }, 1311 .prog_type = BPF_PROG_TYPE_XDP, 1312 .errstr = "call stack", 1313 .result = REJECT, 1314 }, 1315 { 1316 "calls: spill into caller stack frame", 1317 .insns = { 1318 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1319 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1320 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1321 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1322 BPF_EXIT_INSN(), 1323 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), 1324 BPF_MOV64_IMM(BPF_REG_0, 0), 1325 BPF_EXIT_INSN(), 1326 }, 1327 .prog_type = BPF_PROG_TYPE_XDP, 1328 .errstr = "cannot spill", 1329 .result = REJECT, 1330 }, 1331 { 1332 "calls: write into caller stack frame", 1333 .insns = { 1334 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1335 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1336 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1337 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1338 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1339 BPF_EXIT_INSN(), 1340 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42), 1341 BPF_MOV64_IMM(BPF_REG_0, 0), 1342 BPF_EXIT_INSN(), 1343 }, 1344 .prog_type = BPF_PROG_TYPE_XDP, 1345 .result = ACCEPT, 1346 .retval = 42, 1347 }, 1348 { 1349 "calls: write into callee stack frame", 1350 .insns = { 1351 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1352 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), 1353 BPF_EXIT_INSN(), 1354 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), 1355 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8), 1356 BPF_EXIT_INSN(), 1357 }, 1358 .prog_type = BPF_PROG_TYPE_XDP, 1359 .errstr = "cannot return stack pointer", 1360 .result = REJECT, 1361 }, 1362 { 1363 "calls: two calls with stack write and void return", 1364 .insns = { 1365 /* main prog */ 1366 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1367 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1368 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1369 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1370 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1372 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 1373 BPF_EXIT_INSN(), 1374 1375 /* subprog 1 */ 1376 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1377 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1378 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1379 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1380 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1381 BPF_EXIT_INSN(), 1382 1383 /* subprog 2 */ 1384 /* write into stack frame of main prog */ 1385 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 1386 BPF_EXIT_INSN(), /* void return */ 1387 }, 1388 .prog_type = BPF_PROG_TYPE_XDP, 1389 .result = ACCEPT, 1390 }, 1391 { 1392 "calls: ambiguous return value", 1393 .insns = { 1394 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1395 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 1396 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1397 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1398 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1399 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1400 BPF_EXIT_INSN(), 1401 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1402 BPF_MOV64_IMM(BPF_REG_0, 0), 1403 BPF_EXIT_INSN(), 1404 }, 1405 .errstr_unpriv = "allowed for", 1406 .result_unpriv = REJECT, 1407 .errstr = "R0 !read_ok", 1408 .result = REJECT, 1409 }, 1410 { 1411 "calls: two calls that return map_value", 1412 .insns = { 1413 /* main prog */ 1414 /* pass fp-16, fp-8 into a function */ 1415 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1416 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1417 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1418 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1419 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 1420 1421 /* fetch map_value_ptr from the stack of this function */ 1422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 1423 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 1424 /* write into map value */ 1425 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1426 /* fetch second map_value_ptr from the stack */ 1427 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 1428 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 1429 /* write into map value */ 1430 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1431 BPF_MOV64_IMM(BPF_REG_0, 0), 1432 BPF_EXIT_INSN(), 1433 1434 /* subprog 1 */ 1435 /* call 3rd function twice */ 1436 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1437 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1438 /* first time with fp-8 */ 1439 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1440 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1441 /* second time with fp-16 */ 1442 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1443 BPF_EXIT_INSN(), 1444 1445 /* subprog 2 */ 1446 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1447 /* lookup from map */ 1448 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1449 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1450 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1451 BPF_LD_MAP_FD(BPF_REG_1, 0), 1452 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1453 /* write map_value_ptr into stack frame of main prog */ 1454 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1455 BPF_MOV64_IMM(BPF_REG_0, 0), 1456 BPF_EXIT_INSN(), /* return 0 */ 1457 }, 1458 .prog_type = BPF_PROG_TYPE_XDP, 1459 .fixup_map_hash_8b = { 23 }, 1460 .result = ACCEPT, 1461 }, 1462 { 1463 "calls: two calls that return map_value with bool condition", 1464 .insns = { 1465 /* main prog */ 1466 /* pass fp-16, fp-8 into a function */ 1467 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1468 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1469 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1471 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1472 BPF_MOV64_IMM(BPF_REG_0, 0), 1473 BPF_EXIT_INSN(), 1474 1475 /* subprog 1 */ 1476 /* call 3rd function twice */ 1477 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1478 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1479 /* first time with fp-8 */ 1480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 1481 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1482 /* fetch map_value_ptr from the stack of this function */ 1483 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1484 /* write into map value */ 1485 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1486 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1487 /* second time with fp-16 */ 1488 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1489 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1490 /* fetch second map_value_ptr from the stack */ 1491 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 1492 /* write into map value */ 1493 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1494 BPF_EXIT_INSN(), 1495 1496 /* subprog 2 */ 1497 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1498 /* lookup from map */ 1499 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1500 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1501 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1502 BPF_LD_MAP_FD(BPF_REG_1, 0), 1503 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1504 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1505 BPF_MOV64_IMM(BPF_REG_0, 0), 1506 BPF_EXIT_INSN(), /* return 0 */ 1507 /* write map_value_ptr into stack frame of main prog */ 1508 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1509 BPF_MOV64_IMM(BPF_REG_0, 1), 1510 BPF_EXIT_INSN(), /* return 1 */ 1511 }, 1512 .prog_type = BPF_PROG_TYPE_XDP, 1513 .fixup_map_hash_8b = { 23 }, 1514 .result = ACCEPT, 1515 }, 1516 { 1517 "calls: two calls that return map_value with incorrect bool check", 1518 .insns = { 1519 /* main prog */ 1520 /* pass fp-16, fp-8 into a function */ 1521 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1522 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1523 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1524 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1525 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1526 BPF_MOV64_IMM(BPF_REG_0, 0), 1527 BPF_EXIT_INSN(), 1528 1529 /* subprog 1 */ 1530 /* call 3rd function twice */ 1531 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1532 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1533 /* first time with fp-8 */ 1534 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 1535 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 1536 /* fetch map_value_ptr from the stack of this function */ 1537 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 1538 /* write into map value */ 1539 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1540 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 1541 /* second time with fp-16 */ 1542 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1543 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1544 /* fetch second map_value_ptr from the stack */ 1545 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 1546 /* write into map value */ 1547 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1548 BPF_EXIT_INSN(), 1549 1550 /* subprog 2 */ 1551 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1552 /* lookup from map */ 1553 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1554 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1555 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1556 BPF_LD_MAP_FD(BPF_REG_1, 0), 1557 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1558 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1559 BPF_MOV64_IMM(BPF_REG_0, 0), 1560 BPF_EXIT_INSN(), /* return 0 */ 1561 /* write map_value_ptr into stack frame of main prog */ 1562 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1563 BPF_MOV64_IMM(BPF_REG_0, 1), 1564 BPF_EXIT_INSN(), /* return 1 */ 1565 }, 1566 .prog_type = BPF_PROG_TYPE_XDP, 1567 .fixup_map_hash_8b = { 23 }, 1568 .result = REJECT, 1569 .errstr = "R0 invalid mem access 'scalar'", 1570 .result_unpriv = REJECT, 1571 .errstr_unpriv = "invalid read from stack R7 off=-16 size=8", 1572 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1573 }, 1574 { 1575 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1", 1576 .insns = { 1577 /* main prog */ 1578 /* pass fp-16, fp-8 into a function */ 1579 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1580 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1581 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1582 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1583 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1584 BPF_MOV64_IMM(BPF_REG_0, 0), 1585 BPF_EXIT_INSN(), 1586 1587 /* subprog 1 */ 1588 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1589 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1590 /* 1st lookup from map */ 1591 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1592 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1593 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1594 BPF_LD_MAP_FD(BPF_REG_1, 0), 1595 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1596 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1597 BPF_MOV64_IMM(BPF_REG_8, 0), 1598 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1599 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1600 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1601 BPF_MOV64_IMM(BPF_REG_8, 1), 1602 1603 /* 2nd lookup from map */ 1604 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 1605 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1606 BPF_LD_MAP_FD(BPF_REG_1, 0), 1607 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 1608 BPF_FUNC_map_lookup_elem), 1609 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1610 BPF_MOV64_IMM(BPF_REG_9, 0), 1611 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1612 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1613 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1614 BPF_MOV64_IMM(BPF_REG_9, 1), 1615 1616 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1617 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 1618 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1619 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1620 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1621 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 1622 BPF_EXIT_INSN(), 1623 1624 /* subprog 2 */ 1625 /* if arg2 == 1 do *arg1 = 0 */ 1626 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1627 /* fetch map_value_ptr from the stack of this function */ 1628 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1629 /* write into map value */ 1630 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1631 1632 /* if arg4 == 1 do *arg3 = 0 */ 1633 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1634 /* fetch map_value_ptr from the stack of this function */ 1635 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1636 /* write into map value */ 1637 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 1638 BPF_EXIT_INSN(), 1639 }, 1640 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1641 .fixup_map_hash_8b = { 12, 22 }, 1642 .result = REJECT, 1643 .errstr = "invalid access to map value, value_size=8 off=2 size=8", 1644 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1645 }, 1646 { 1647 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2", 1648 .insns = { 1649 /* main prog */ 1650 /* pass fp-16, fp-8 into a function */ 1651 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1652 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1653 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1654 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1655 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1656 BPF_MOV64_IMM(BPF_REG_0, 0), 1657 BPF_EXIT_INSN(), 1658 1659 /* subprog 1 */ 1660 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1661 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1662 /* 1st lookup from map */ 1663 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1664 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1665 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1666 BPF_LD_MAP_FD(BPF_REG_1, 0), 1667 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1668 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1669 BPF_MOV64_IMM(BPF_REG_8, 0), 1670 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1671 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1672 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1673 BPF_MOV64_IMM(BPF_REG_8, 1), 1674 1675 /* 2nd lookup from map */ 1676 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 1677 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1678 BPF_LD_MAP_FD(BPF_REG_1, 0), 1679 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 1680 BPF_FUNC_map_lookup_elem), 1681 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1682 BPF_MOV64_IMM(BPF_REG_9, 0), 1683 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1684 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1685 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1686 BPF_MOV64_IMM(BPF_REG_9, 1), 1687 1688 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1689 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 1690 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1691 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1692 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1693 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 1694 BPF_EXIT_INSN(), 1695 1696 /* subprog 2 */ 1697 /* if arg2 == 1 do *arg1 = 0 */ 1698 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1699 /* fetch map_value_ptr from the stack of this function */ 1700 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1701 /* write into map value */ 1702 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1703 1704 /* if arg4 == 1 do *arg3 = 0 */ 1705 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1706 /* fetch map_value_ptr from the stack of this function */ 1707 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1708 /* write into map value */ 1709 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1710 BPF_EXIT_INSN(), 1711 }, 1712 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1713 .fixup_map_hash_8b = { 12, 22 }, 1714 .result = ACCEPT, 1715 }, 1716 { 1717 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3", 1718 .insns = { 1719 /* main prog */ 1720 /* pass fp-16, fp-8 into a function */ 1721 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1722 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1723 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1724 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1725 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), 1726 BPF_MOV64_IMM(BPF_REG_0, 0), 1727 BPF_EXIT_INSN(), 1728 1729 /* subprog 1 */ 1730 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1731 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1732 /* 1st lookup from map */ 1733 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0), 1734 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1735 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 1736 BPF_LD_MAP_FD(BPF_REG_1, 0), 1737 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1738 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1739 BPF_MOV64_IMM(BPF_REG_8, 0), 1740 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1741 /* write map_value_ptr into stack frame of main prog at fp-8 */ 1742 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1743 BPF_MOV64_IMM(BPF_REG_8, 1), 1744 1745 /* 2nd lookup from map */ 1746 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1747 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 1748 BPF_LD_MAP_FD(BPF_REG_1, 0), 1749 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1750 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1751 BPF_MOV64_IMM(BPF_REG_9, 0), // 26 1752 BPF_JMP_IMM(BPF_JA, 0, 0, 2), 1753 /* write map_value_ptr into stack frame of main prog at fp-16 */ 1754 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1755 BPF_MOV64_IMM(BPF_REG_9, 1), 1756 1757 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1758 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30 1759 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1760 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1761 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1762 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34 1763 BPF_JMP_IMM(BPF_JA, 0, 0, -30), 1764 1765 /* subprog 2 */ 1766 /* if arg2 == 1 do *arg1 = 0 */ 1767 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1768 /* fetch map_value_ptr from the stack of this function */ 1769 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1770 /* write into map value */ 1771 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1772 1773 /* if arg4 == 1 do *arg3 = 0 */ 1774 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1775 /* fetch map_value_ptr from the stack of this function */ 1776 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1777 /* write into map value */ 1778 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 1779 BPF_JMP_IMM(BPF_JA, 0, 0, -8), 1780 }, 1781 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1782 .fixup_map_hash_8b = { 12, 22 }, 1783 .result = REJECT, 1784 .errstr = "invalid access to map value, value_size=8 off=2 size=8", 1785 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1786 }, 1787 { 1788 "calls: two calls that receive map_value_ptr_or_null via arg. test1", 1789 .insns = { 1790 /* main prog */ 1791 /* pass fp-16, fp-8 into a function */ 1792 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1793 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1794 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1795 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1796 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1797 BPF_MOV64_IMM(BPF_REG_0, 0), 1798 BPF_EXIT_INSN(), 1799 1800 /* subprog 1 */ 1801 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1802 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1803 /* 1st lookup from map */ 1804 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1805 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1806 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1807 BPF_LD_MAP_FD(BPF_REG_1, 0), 1808 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1809 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 1810 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1811 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1812 BPF_MOV64_IMM(BPF_REG_8, 0), 1813 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1814 BPF_MOV64_IMM(BPF_REG_8, 1), 1815 1816 /* 2nd lookup from map */ 1817 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1818 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1819 BPF_LD_MAP_FD(BPF_REG_1, 0), 1820 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1821 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 1822 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1823 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1824 BPF_MOV64_IMM(BPF_REG_9, 0), 1825 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1826 BPF_MOV64_IMM(BPF_REG_9, 1), 1827 1828 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1829 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1830 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1831 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1832 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1833 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1834 BPF_EXIT_INSN(), 1835 1836 /* subprog 2 */ 1837 /* if arg2 == 1 do *arg1 = 0 */ 1838 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1839 /* fetch map_value_ptr from the stack of this function */ 1840 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1841 /* write into map value */ 1842 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1843 1844 /* if arg4 == 1 do *arg3 = 0 */ 1845 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 1846 /* fetch map_value_ptr from the stack of this function */ 1847 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1848 /* write into map value */ 1849 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1850 BPF_EXIT_INSN(), 1851 }, 1852 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1853 .fixup_map_hash_8b = { 12, 22 }, 1854 .result = ACCEPT, 1855 }, 1856 { 1857 "calls: two calls that receive map_value_ptr_or_null via arg. test2", 1858 .insns = { 1859 /* main prog */ 1860 /* pass fp-16, fp-8 into a function */ 1861 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1862 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1863 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1864 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 1865 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 1866 BPF_MOV64_IMM(BPF_REG_0, 0), 1867 BPF_EXIT_INSN(), 1868 1869 /* subprog 1 */ 1870 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 1871 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 1872 /* 1st lookup from map */ 1873 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 1874 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1875 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1876 BPF_LD_MAP_FD(BPF_REG_1, 0), 1877 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1878 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 1879 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 1880 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1881 BPF_MOV64_IMM(BPF_REG_8, 0), 1882 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1883 BPF_MOV64_IMM(BPF_REG_8, 1), 1884 1885 /* 2nd lookup from map */ 1886 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 1887 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 1888 BPF_LD_MAP_FD(BPF_REG_1, 0), 1889 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 1890 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 1891 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 1892 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 1893 BPF_MOV64_IMM(BPF_REG_9, 0), 1894 BPF_JMP_IMM(BPF_JA, 0, 0, 1), 1895 BPF_MOV64_IMM(BPF_REG_9, 1), 1896 1897 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 1898 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 1899 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 1900 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 1901 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 1902 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1903 BPF_EXIT_INSN(), 1904 1905 /* subprog 2 */ 1906 /* if arg2 == 1 do *arg1 = 0 */ 1907 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 1908 /* fetch map_value_ptr from the stack of this function */ 1909 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 1910 /* write into map value */ 1911 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1912 1913 /* if arg4 == 0 do *arg3 = 0 */ 1914 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2), 1915 /* fetch map_value_ptr from the stack of this function */ 1916 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 1917 /* write into map value */ 1918 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 1919 BPF_EXIT_INSN(), 1920 }, 1921 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1922 .fixup_map_hash_8b = { 12, 22 }, 1923 .result = REJECT, 1924 .errstr = "R0 invalid mem access 'scalar'", 1925 }, 1926 { 1927 "calls: pkt_ptr spill into caller stack", 1928 .insns = { 1929 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 1930 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 1931 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 1932 BPF_EXIT_INSN(), 1933 1934 /* subprog 1 */ 1935 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1936 offsetof(struct __sk_buff, data)), 1937 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1938 offsetof(struct __sk_buff, data_end)), 1939 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1940 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1941 /* spill unchecked pkt_ptr into stack of caller */ 1942 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 1943 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 1944 /* now the pkt range is verified, read pkt_ptr from stack */ 1945 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 1946 /* write 4 bytes into packet */ 1947 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 1948 BPF_EXIT_INSN(), 1949 }, 1950 .result = ACCEPT, 1951 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1952 .retval = POINTER_VALUE, 1953 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1954 }, 1955 { 1956 "calls: pkt_ptr spill into caller stack 2", 1957 .insns = { 1958 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 1959 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 1960 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 1961 /* Marking is still kept, but not in all cases safe. */ 1962 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 1963 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 1964 BPF_EXIT_INSN(), 1965 1966 /* subprog 1 */ 1967 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1968 offsetof(struct __sk_buff, data)), 1969 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 1970 offsetof(struct __sk_buff, data_end)), 1971 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 1972 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1973 /* spill unchecked pkt_ptr into stack of caller */ 1974 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 1975 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 1976 /* now the pkt range is verified, read pkt_ptr from stack */ 1977 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 1978 /* write 4 bytes into packet */ 1979 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 1980 BPF_EXIT_INSN(), 1981 }, 1982 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1983 .errstr = "invalid access to packet", 1984 .result = REJECT, 1985 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 1986 }, 1987 { 1988 "calls: pkt_ptr spill into caller stack 3", 1989 .insns = { 1990 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 1991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 1992 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 1993 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 1994 /* Marking is still kept and safe here. */ 1995 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 1996 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 1997 BPF_EXIT_INSN(), 1998 1999 /* subprog 1 */ 2000 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2001 offsetof(struct __sk_buff, data)), 2002 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2003 offsetof(struct __sk_buff, data_end)), 2004 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2005 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2006 /* spill unchecked pkt_ptr into stack of caller */ 2007 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2008 BPF_MOV64_IMM(BPF_REG_5, 0), 2009 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2010 BPF_MOV64_IMM(BPF_REG_5, 1), 2011 /* now the pkt range is verified, read pkt_ptr from stack */ 2012 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 2013 /* write 4 bytes into packet */ 2014 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2015 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2016 BPF_EXIT_INSN(), 2017 }, 2018 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2019 .result = ACCEPT, 2020 .retval = 1, 2021 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2022 }, 2023 { 2024 "calls: pkt_ptr spill into caller stack 4", 2025 .insns = { 2026 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2027 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2028 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2029 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 2030 /* Check marking propagated. */ 2031 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2032 BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 2033 BPF_EXIT_INSN(), 2034 2035 /* subprog 1 */ 2036 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2037 offsetof(struct __sk_buff, data)), 2038 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2039 offsetof(struct __sk_buff, data_end)), 2040 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2041 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2042 /* spill unchecked pkt_ptr into stack of caller */ 2043 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2044 BPF_MOV64_IMM(BPF_REG_5, 0), 2045 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 2046 BPF_MOV64_IMM(BPF_REG_5, 1), 2047 /* don't read back pkt_ptr from stack here */ 2048 /* write 4 bytes into packet */ 2049 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2050 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2051 BPF_EXIT_INSN(), 2052 }, 2053 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2054 .result = ACCEPT, 2055 .retval = 1, 2056 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2057 }, 2058 { 2059 "calls: pkt_ptr spill into caller stack 5", 2060 .insns = { 2061 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2062 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2063 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0), 2064 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2065 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2066 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2067 BPF_EXIT_INSN(), 2068 2069 /* subprog 1 */ 2070 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2071 offsetof(struct __sk_buff, data)), 2072 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2073 offsetof(struct __sk_buff, data_end)), 2074 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2075 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2076 BPF_MOV64_IMM(BPF_REG_5, 0), 2077 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2078 /* spill checked pkt_ptr into stack of caller */ 2079 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2080 BPF_MOV64_IMM(BPF_REG_5, 1), 2081 /* don't read back pkt_ptr from stack here */ 2082 /* write 4 bytes into packet */ 2083 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2084 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2085 BPF_EXIT_INSN(), 2086 }, 2087 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2088 .errstr = "same insn cannot be used with different", 2089 .result = REJECT, 2090 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2091 }, 2092 { 2093 "calls: pkt_ptr spill into caller stack 6", 2094 .insns = { 2095 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2096 offsetof(struct __sk_buff, data_end)), 2097 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2099 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2100 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2101 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2102 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2103 BPF_EXIT_INSN(), 2104 2105 /* subprog 1 */ 2106 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2107 offsetof(struct __sk_buff, data)), 2108 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2109 offsetof(struct __sk_buff, data_end)), 2110 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2112 BPF_MOV64_IMM(BPF_REG_5, 0), 2113 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2114 /* spill checked pkt_ptr into stack of caller */ 2115 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2116 BPF_MOV64_IMM(BPF_REG_5, 1), 2117 /* don't read back pkt_ptr from stack here */ 2118 /* write 4 bytes into packet */ 2119 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2120 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2121 BPF_EXIT_INSN(), 2122 }, 2123 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2124 .errstr = "R4 invalid mem access", 2125 .result = REJECT, 2126 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2127 }, 2128 { 2129 "calls: pkt_ptr spill into caller stack 7", 2130 .insns = { 2131 BPF_MOV64_IMM(BPF_REG_2, 0), 2132 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2134 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2135 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2136 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2137 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2138 BPF_EXIT_INSN(), 2139 2140 /* subprog 1 */ 2141 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2142 offsetof(struct __sk_buff, data)), 2143 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2144 offsetof(struct __sk_buff, data_end)), 2145 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2146 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2147 BPF_MOV64_IMM(BPF_REG_5, 0), 2148 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2149 /* spill checked pkt_ptr into stack of caller */ 2150 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2151 BPF_MOV64_IMM(BPF_REG_5, 1), 2152 /* don't read back pkt_ptr from stack here */ 2153 /* write 4 bytes into packet */ 2154 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2155 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2156 BPF_EXIT_INSN(), 2157 }, 2158 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2159 .errstr = "R4 invalid mem access", 2160 .result = REJECT, 2161 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2162 }, 2163 { 2164 "calls: pkt_ptr spill into caller stack 8", 2165 .insns = { 2166 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2167 offsetof(struct __sk_buff, data)), 2168 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2169 offsetof(struct __sk_buff, data_end)), 2170 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2171 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2172 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 2173 BPF_EXIT_INSN(), 2174 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2175 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2176 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2177 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2178 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2179 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2180 BPF_EXIT_INSN(), 2181 2182 /* subprog 1 */ 2183 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2184 offsetof(struct __sk_buff, data)), 2185 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2186 offsetof(struct __sk_buff, data_end)), 2187 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2189 BPF_MOV64_IMM(BPF_REG_5, 0), 2190 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 2191 /* spill checked pkt_ptr into stack of caller */ 2192 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2193 BPF_MOV64_IMM(BPF_REG_5, 1), 2194 /* don't read back pkt_ptr from stack here */ 2195 /* write 4 bytes into packet */ 2196 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2197 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2198 BPF_EXIT_INSN(), 2199 }, 2200 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2201 .result = ACCEPT, 2202 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2203 }, 2204 { 2205 "calls: pkt_ptr spill into caller stack 9", 2206 .insns = { 2207 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2208 offsetof(struct __sk_buff, data)), 2209 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2210 offsetof(struct __sk_buff, data_end)), 2211 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2213 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 2214 BPF_EXIT_INSN(), 2215 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 2216 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 2217 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2218 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 2219 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 2220 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 2221 BPF_EXIT_INSN(), 2222 2223 /* subprog 1 */ 2224 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2225 offsetof(struct __sk_buff, data)), 2226 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 2227 offsetof(struct __sk_buff, data_end)), 2228 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 2229 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 2230 BPF_MOV64_IMM(BPF_REG_5, 0), 2231 /* spill unchecked pkt_ptr into stack of caller */ 2232 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 2233 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 2234 BPF_MOV64_IMM(BPF_REG_5, 1), 2235 /* don't read back pkt_ptr from stack here */ 2236 /* write 4 bytes into packet */ 2237 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 2238 BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 2239 BPF_EXIT_INSN(), 2240 }, 2241 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2242 .errstr = "invalid access to packet", 2243 .result = REJECT, 2244 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 2245 }, 2246 { 2247 "calls: caller stack init to zero or map_value_or_null", 2248 .insns = { 2249 BPF_MOV64_IMM(BPF_REG_0, 0), 2250 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 2251 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2252 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2253 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2254 /* fetch map_value_or_null or const_zero from stack */ 2255 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 2256 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 2257 /* store into map_value */ 2258 BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0), 2259 BPF_EXIT_INSN(), 2260 2261 /* subprog 1 */ 2262 /* if (ctx == 0) return; */ 2263 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8), 2264 /* else bpf_map_lookup() and *(fp - 8) = r0 */ 2265 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 2266 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2267 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2268 BPF_LD_MAP_FD(BPF_REG_1, 0), 2269 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2270 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 2271 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 2272 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 2273 BPF_EXIT_INSN(), 2274 }, 2275 .fixup_map_hash_8b = { 13 }, 2276 .result = ACCEPT, 2277 .prog_type = BPF_PROG_TYPE_XDP, 2278 }, 2279 { 2280 "calls: stack init to zero and pruning", 2281 .insns = { 2282 /* first make allocated_stack 16 byte */ 2283 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 2284 /* now fork the execution such that the false branch 2285 * of JGT insn will be verified second and it skisp zero 2286 * init of fp-8 stack slot. If stack liveness marking 2287 * is missing live_read marks from call map_lookup 2288 * processing then pruning will incorrectly assume 2289 * that fp-8 stack slot was unused in the fall-through 2290 * branch and will accept the program incorrectly 2291 */ 2292 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), 2293 BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2), 2294 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2295 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 2296 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2297 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2298 BPF_LD_MAP_FD(BPF_REG_1, 0), 2299 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 2300 BPF_MOV64_IMM(BPF_REG_0, 0), 2301 BPF_EXIT_INSN(), 2302 }, 2303 .fixup_map_hash_48b = { 7 }, 2304 .errstr_unpriv = "invalid read from stack R2 off -8+0 size 8", 2305 .result_unpriv = REJECT, 2306 /* in privileged mode reads from uninitialized stack locations are permitted */ 2307 .result = ACCEPT, 2308 }, 2309 { 2310 "calls: ctx read at start of subprog", 2311 .insns = { 2312 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 2313 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 2314 BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0), 2315 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2316 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 2317 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2318 BPF_EXIT_INSN(), 2319 BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 2320 BPF_MOV64_IMM(BPF_REG_0, 0), 2321 BPF_EXIT_INSN(), 2322 }, 2323 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2324 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2325 .result_unpriv = REJECT, 2326 .result = ACCEPT, 2327 }, 2328 { 2329 "calls: cross frame pruning", 2330 .insns = { 2331 /* r8 = !!random(); 2332 * call pruner() 2333 * if (r8) 2334 * do something bad; 2335 */ 2336 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2337 BPF_MOV64_IMM(BPF_REG_8, 0), 2338 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2339 BPF_MOV64_IMM(BPF_REG_8, 1), 2340 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), 2341 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2342 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 2343 BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 2344 BPF_MOV64_IMM(BPF_REG_0, 0), 2345 BPF_EXIT_INSN(), 2346 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 2347 BPF_EXIT_INSN(), 2348 }, 2349 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2350 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2351 .errstr = "!read_ok", 2352 .result = REJECT, 2353 }, 2354 { 2355 "calls: cross frame pruning - liveness propagation", 2356 .insns = { 2357 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2358 BPF_MOV64_IMM(BPF_REG_8, 0), 2359 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2360 BPF_MOV64_IMM(BPF_REG_8, 1), 2361 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 2362 BPF_MOV64_IMM(BPF_REG_9, 0), 2363 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2364 BPF_MOV64_IMM(BPF_REG_9, 1), 2365 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2366 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 2367 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 2368 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0), 2369 BPF_MOV64_IMM(BPF_REG_0, 0), 2370 BPF_EXIT_INSN(), 2371 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 2372 BPF_EXIT_INSN(), 2373 }, 2374 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2375 .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 2376 .errstr = "!read_ok", 2377 .result = REJECT, 2378 }, 2379 /* Make sure that verifier.c:states_equal() considers IDs from all 2380 * frames when building 'idmap' for check_ids(). 2381 */ 2382 { 2383 "calls: check_ids() across call boundary", 2384 .insns = { 2385 /* Function main() */ 2386 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 2387 /* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 2388 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2390 BPF_LD_MAP_FD(BPF_REG_1, 2391 0), 2392 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 2393 BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24), 2394 /* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 2395 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 2396 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 2397 BPF_LD_MAP_FD(BPF_REG_1, 2398 0), 2399 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 2400 BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32), 2401 /* call foo(&fp[-24], &fp[-32]) ; both arguments have IDs in the current 2402 * ; stack frame 2403 */ 2404 BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP), 2405 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24), 2406 BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), 2407 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32), 2408 BPF_CALL_REL(2), 2409 /* exit 0 */ 2410 BPF_MOV64_IMM(BPF_REG_0, 0), 2411 BPF_EXIT_INSN(), 2412 /* Function foo() 2413 * 2414 * r9 = &frame[0].fp[-24] ; save arguments in the callee saved registers, 2415 * r8 = &frame[0].fp[-32] ; arguments are pointers to pointers to map value 2416 */ 2417 BPF_MOV64_REG(BPF_REG_9, BPF_REG_1), 2418 BPF_MOV64_REG(BPF_REG_8, BPF_REG_2), 2419 /* r7 = ktime_get_ns() */ 2420 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 2421 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 2422 /* r6 = ktime_get_ns() */ 2423 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 2424 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 2425 /* if r6 > r7 goto +1 ; no new information about the state is derived from 2426 * ; this check, thus produced verifier states differ 2427 * ; only in 'insn_idx' 2428 * r9 = r8 2429 */ 2430 BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), 2431 BPF_MOV64_REG(BPF_REG_9, BPF_REG_8), 2432 /* r9 = *r9 ; verifier gets to this point via two paths: 2433 * ; (I) one including r9 = r8, verified first; 2434 * ; (II) one excluding r9 = r8, verified next. 2435 * ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id. 2436 * ; Suppose that checkpoint is created here via path (I). 2437 * ; When verifying via (II) the r9.id must be compared against 2438 * ; frame[0].fp[-24].id, otherwise (I) and (II) would be 2439 * ; incorrectly deemed equivalent. 2440 * if r9 == 0 goto <exit> 2441 */ 2442 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0), 2443 BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1), 2444 /* r8 = *r8 ; read map value via r8, this is not safe 2445 * r0 = *r8 ; because r8 might be not equal to r9. 2446 */ 2447 BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0), 2448 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0), 2449 /* exit 0 */ 2450 BPF_MOV64_IMM(BPF_REG_0, 0), 2451 BPF_EXIT_INSN(), 2452 }, 2453 .flags = BPF_F_TEST_STATE_FREQ, 2454 .fixup_map_hash_8b = { 3, 9 }, 2455 .result = REJECT, 2456 .errstr = "R8 invalid mem access 'map_value_or_null'", 2457 .result_unpriv = REJECT, 2458 .errstr_unpriv = "", 2459 .prog_type = BPF_PROG_TYPE_CGROUP_SKB, 2460 }, 2461