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