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