aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2017-12-14 20:55:07 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2017-12-17 14:34:35 -0500
commita7ff3eca95a5f9bc24132b5975f40dac10710ed1 (patch)
treec7994f61b98c7f88b790dab296545e5a7a9b1221 /tools
parentf4d7e40a5b7157e1329c3c5b10f60d8289fc2941 (diff)
selftests/bpf: add verifier tests for bpf_call
Add extensive set of tests for bpf_call verification logic: calls: basic sanity calls: using r0 returned by callee calls: callee is using r1 calls: callee using args1 calls: callee using wrong args2 calls: callee using two args calls: callee changing pkt pointers calls: two calls with args calls: two calls with bad jump calls: recursive call. test1 calls: recursive call. test2 calls: unreachable code calls: invalid call calls: jumping across function bodies. test1 calls: jumping across function bodies. test2 calls: call without exit calls: call into middle of ld_imm64 calls: call into middle of other call calls: two calls with bad fallthrough calls: two calls with stack read calls: two calls with stack write calls: spill into caller stack frame calls: two calls with stack write and void return calls: ambiguous return value calls: two calls that return map_value calls: two calls that return map_value with bool condition calls: two calls that return map_value with incorrect bool check calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1 calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2 calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3 calls: two calls that receive map_value_ptr_or_null via arg. test1 calls: two calls that receive map_value_ptr_or_null via arg. test2 calls: pkt_ptr spill into caller stack Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c961
1 files changed, 960 insertions, 1 deletions
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 3c64f30cf63c..88f389c6ec48 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -2,6 +2,7 @@
2 * Testsuite for eBPF verifier 2 * Testsuite for eBPF verifier
3 * 3 *
4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com 4 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
5 * Copyright (c) 2017 Facebook
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 8 * modify it under the terms of version 2 of the GNU General Public
@@ -277,7 +278,7 @@ static struct bpf_test tests[] = {
277 .insns = { 278 .insns = {
278 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2), 279 BPF_ALU64_REG(BPF_MOV, BPF_REG_0, BPF_REG_2),
279 }, 280 },
280 .errstr = "jump out of range", 281 .errstr = "not an exit",
281 .result = REJECT, 282 .result = REJECT,
282 }, 283 },
283 { 284 {
@@ -8097,6 +8098,964 @@ static struct bpf_test tests[] = {
8097 .result = REJECT, 8098 .result = REJECT,
8098 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK, 8099 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
8099 }, 8100 },
8101 {
8102 "calls: basic sanity",
8103 .insns = {
8104 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8105 BPF_MOV64_IMM(BPF_REG_0, 1),
8106 BPF_EXIT_INSN(),
8107 BPF_MOV64_IMM(BPF_REG_0, 2),
8108 BPF_EXIT_INSN(),
8109 },
8110 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8111 .result = ACCEPT,
8112 },
8113 {
8114 "calls: using r0 returned by callee",
8115 .insns = {
8116 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8117 BPF_EXIT_INSN(),
8118 BPF_MOV64_IMM(BPF_REG_0, 2),
8119 BPF_EXIT_INSN(),
8120 },
8121 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8122 .result = ACCEPT,
8123 },
8124 {
8125 "calls: callee is using r1",
8126 .insns = {
8127 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8128 BPF_EXIT_INSN(),
8129 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8130 offsetof(struct __sk_buff, len)),
8131 BPF_EXIT_INSN(),
8132 },
8133 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
8134 .result = ACCEPT,
8135 },
8136 {
8137 "calls: callee using args1",
8138 .insns = {
8139 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8140 BPF_EXIT_INSN(),
8141 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8142 BPF_EXIT_INSN(),
8143 },
8144 .errstr_unpriv = "allowed for root only",
8145 .result_unpriv = REJECT,
8146 .result = ACCEPT,
8147 },
8148 {
8149 "calls: callee using wrong args2",
8150 .insns = {
8151 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8152 BPF_EXIT_INSN(),
8153 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
8154 BPF_EXIT_INSN(),
8155 },
8156 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8157 .errstr = "R2 !read_ok",
8158 .result = REJECT,
8159 },
8160 {
8161 "calls: callee using two args",
8162 .insns = {
8163 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8164 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
8165 offsetof(struct __sk_buff, len)),
8166 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
8167 offsetof(struct __sk_buff, len)),
8168 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8169 BPF_EXIT_INSN(),
8170 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
8171 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
8172 BPF_EXIT_INSN(),
8173 },
8174 .errstr_unpriv = "allowed for root only",
8175 .result_unpriv = REJECT,
8176 .result = ACCEPT,
8177 },
8178 {
8179 "calls: callee changing pkt pointers",
8180 .insns = {
8181 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
8182 offsetof(struct xdp_md, data)),
8183 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
8184 offsetof(struct xdp_md, data_end)),
8185 BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
8186 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
8187 BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
8188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8189 /* clear_all_pkt_pointers() has to walk all frames
8190 * to make sure that pkt pointers in the caller
8191 * are cleared when callee is calling a helper that
8192 * adjusts packet size
8193 */
8194 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
8195 BPF_MOV32_IMM(BPF_REG_0, 0),
8196 BPF_EXIT_INSN(),
8197 BPF_MOV64_IMM(BPF_REG_2, 0),
8198 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8199 BPF_FUNC_xdp_adjust_head),
8200 BPF_EXIT_INSN(),
8201 },
8202 .result = REJECT,
8203 .errstr = "R6 invalid mem access 'inv'",
8204 .prog_type = BPF_PROG_TYPE_XDP,
8205 },
8206 {
8207 "calls: two calls with args",
8208 .insns = {
8209 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8210 BPF_EXIT_INSN(),
8211 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8212 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
8213 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
8214 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8215 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8216 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
8217 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8218 BPF_EXIT_INSN(),
8219 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8220 offsetof(struct __sk_buff, len)),
8221 BPF_EXIT_INSN(),
8222 },
8223 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8224 .result = ACCEPT,
8225 },
8226 {
8227 "calls: two calls with bad jump",
8228 .insns = {
8229 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8230 BPF_EXIT_INSN(),
8231 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8232 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
8233 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
8234 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8235 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8236 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
8237 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8238 BPF_EXIT_INSN(),
8239 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8240 offsetof(struct __sk_buff, len)),
8241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
8242 BPF_EXIT_INSN(),
8243 },
8244 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8245 .errstr = "jump out of range from insn 11 to 9",
8246 .result = REJECT,
8247 },
8248 {
8249 "calls: recursive call. test1",
8250 .insns = {
8251 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8252 BPF_EXIT_INSN(),
8253 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
8254 BPF_EXIT_INSN(),
8255 },
8256 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8257 .errstr = "back-edge",
8258 .result = REJECT,
8259 },
8260 {
8261 "calls: recursive call. test2",
8262 .insns = {
8263 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8264 BPF_EXIT_INSN(),
8265 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
8266 BPF_EXIT_INSN(),
8267 },
8268 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8269 .errstr = "back-edge",
8270 .result = REJECT,
8271 },
8272 {
8273 "calls: unreachable code",
8274 .insns = {
8275 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8276 BPF_EXIT_INSN(),
8277 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8278 BPF_EXIT_INSN(),
8279 BPF_MOV64_IMM(BPF_REG_0, 0),
8280 BPF_EXIT_INSN(),
8281 BPF_MOV64_IMM(BPF_REG_0, 0),
8282 BPF_EXIT_INSN(),
8283 },
8284 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8285 .errstr = "unreachable insn 6",
8286 .result = REJECT,
8287 },
8288 {
8289 "calls: invalid call",
8290 .insns = {
8291 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8292 BPF_EXIT_INSN(),
8293 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
8294 BPF_EXIT_INSN(),
8295 },
8296 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8297 .errstr = "invalid destination",
8298 .result = REJECT,
8299 },
8300 {
8301 "calls: jumping across function bodies. test1",
8302 .insns = {
8303 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8304 BPF_MOV64_IMM(BPF_REG_0, 0),
8305 BPF_EXIT_INSN(),
8306 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
8307 BPF_EXIT_INSN(),
8308 },
8309 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8310 .errstr = "jump out of range",
8311 .result = REJECT,
8312 },
8313 {
8314 "calls: jumping across function bodies. test2",
8315 .insns = {
8316 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
8317 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8318 BPF_MOV64_IMM(BPF_REG_0, 0),
8319 BPF_EXIT_INSN(),
8320 BPF_EXIT_INSN(),
8321 },
8322 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8323 .errstr = "jump out of range",
8324 .result = REJECT,
8325 },
8326 {
8327 "calls: call without exit",
8328 .insns = {
8329 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8330 BPF_EXIT_INSN(),
8331 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8332 BPF_EXIT_INSN(),
8333 BPF_MOV64_IMM(BPF_REG_0, 0),
8334 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
8335 },
8336 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8337 .errstr = "not an exit",
8338 .result = REJECT,
8339 },
8340 {
8341 "calls: call into middle of ld_imm64",
8342 .insns = {
8343 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8344 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8345 BPF_MOV64_IMM(BPF_REG_0, 0),
8346 BPF_EXIT_INSN(),
8347 BPF_LD_IMM64(BPF_REG_0, 0),
8348 BPF_EXIT_INSN(),
8349 },
8350 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8351 .errstr = "last insn",
8352 .result = REJECT,
8353 },
8354 {
8355 "calls: call into middle of other call",
8356 .insns = {
8357 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8358 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8359 BPF_MOV64_IMM(BPF_REG_0, 0),
8360 BPF_EXIT_INSN(),
8361 BPF_MOV64_IMM(BPF_REG_0, 0),
8362 BPF_MOV64_IMM(BPF_REG_0, 0),
8363 BPF_EXIT_INSN(),
8364 },
8365 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8366 .errstr = "last insn",
8367 .result = REJECT,
8368 },
8369 {
8370 "calls: two calls with bad fallthrough",
8371 .insns = {
8372 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8373 BPF_EXIT_INSN(),
8374 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8375 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
8376 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
8377 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8378 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8379 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
8380 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8381 BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
8382 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
8383 offsetof(struct __sk_buff, len)),
8384 BPF_EXIT_INSN(),
8385 },
8386 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
8387 .errstr = "not an exit",
8388 .result = REJECT,
8389 },
8390 {
8391 "calls: two calls with stack read",
8392 .insns = {
8393 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8394 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8395 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8396 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8397 BPF_EXIT_INSN(),
8398 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8399 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
8400 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
8401 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8402 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8403 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
8404 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
8405 BPF_EXIT_INSN(),
8406 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8407 BPF_EXIT_INSN(),
8408 },
8409 .prog_type = BPF_PROG_TYPE_XDP,
8410 .result = ACCEPT,
8411 },
8412 {
8413 "calls: two calls with stack write",
8414 .insns = {
8415 /* main prog */
8416 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8417 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8418 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8419 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8420 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8421 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
8423 BPF_EXIT_INSN(),
8424
8425 /* subprog 1 */
8426 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8427 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8428 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
8429 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
8430 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8431 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8432 BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
8433 BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
8434 /* write into stack frame of main prog */
8435 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8436 BPF_EXIT_INSN(),
8437
8438 /* subprog 2 */
8439 /* read from stack frame of main prog */
8440 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
8441 BPF_EXIT_INSN(),
8442 },
8443 .prog_type = BPF_PROG_TYPE_XDP,
8444 .result = ACCEPT,
8445 },
8446 {
8447 "calls: spill into caller stack frame",
8448 .insns = {
8449 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8450 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8451 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8452 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8453 BPF_EXIT_INSN(),
8454 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
8455 BPF_MOV64_IMM(BPF_REG_0, 0),
8456 BPF_EXIT_INSN(),
8457 },
8458 .prog_type = BPF_PROG_TYPE_XDP,
8459 .errstr = "cannot spill",
8460 .result = REJECT,
8461 },
8462 {
8463 "calls: two calls with stack write and void return",
8464 .insns = {
8465 /* main prog */
8466 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8467 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8468 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8469 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8471 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8472 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
8473 BPF_EXIT_INSN(),
8474
8475 /* subprog 1 */
8476 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8477 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8478 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8479 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8481 BPF_EXIT_INSN(),
8482
8483 /* subprog 2 */
8484 /* write into stack frame of main prog */
8485 BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
8486 BPF_EXIT_INSN(), /* void return */
8487 },
8488 .prog_type = BPF_PROG_TYPE_XDP,
8489 .result = ACCEPT,
8490 },
8491 {
8492 "calls: ambiguous return value",
8493 .insns = {
8494 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8495 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
8496 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
8497 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8498 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8499 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
8500 BPF_EXIT_INSN(),
8501 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
8502 BPF_MOV64_IMM(BPF_REG_0, 0),
8503 BPF_EXIT_INSN(),
8504 },
8505 .errstr_unpriv = "allowed for root only",
8506 .result_unpriv = REJECT,
8507 .errstr = "R0 !read_ok",
8508 .result = REJECT,
8509 },
8510 {
8511 "calls: two calls that return map_value",
8512 .insns = {
8513 /* main prog */
8514 /* pass fp-16, fp-8 into a function */
8515 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8516 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8517 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8518 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8519 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
8520
8521 /* fetch map_value_ptr from the stack of this function */
8522 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
8523 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
8524 /* write into map value */
8525 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8526 /* fetch secound map_value_ptr from the stack */
8527 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
8528 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
8529 /* write into map value */
8530 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8531 BPF_MOV64_IMM(BPF_REG_0, 0),
8532 BPF_EXIT_INSN(),
8533
8534 /* subprog 1 */
8535 /* call 3rd function twice */
8536 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8537 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8538 /* first time with fp-8 */
8539 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
8540 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8541 /* second time with fp-16 */
8542 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8543 BPF_EXIT_INSN(),
8544
8545 /* subprog 2 */
8546 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8547 /* lookup from map */
8548 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8549 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8550 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8551 BPF_LD_MAP_FD(BPF_REG_1, 0),
8552 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8553 BPF_FUNC_map_lookup_elem),
8554 /* write map_value_ptr into stack frame of main prog */
8555 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8556 BPF_MOV64_IMM(BPF_REG_0, 0),
8557 BPF_EXIT_INSN(), /* return 0 */
8558 },
8559 .prog_type = BPF_PROG_TYPE_XDP,
8560 .fixup_map1 = { 23 },
8561 .result = ACCEPT,
8562 },
8563 {
8564 "calls: two calls that return map_value with bool condition",
8565 .insns = {
8566 /* main prog */
8567 /* pass fp-16, fp-8 into a function */
8568 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8569 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8570 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8571 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8572 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8573 BPF_MOV64_IMM(BPF_REG_0, 0),
8574 BPF_EXIT_INSN(),
8575
8576 /* subprog 1 */
8577 /* call 3rd function twice */
8578 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8579 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8580 /* first time with fp-8 */
8581 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
8582 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
8583 /* fetch map_value_ptr from the stack of this function */
8584 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
8585 /* write into map value */
8586 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8587 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8588 /* second time with fp-16 */
8589 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8590 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
8591 /* fetch secound map_value_ptr from the stack */
8592 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
8593 /* write into map value */
8594 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8595 BPF_EXIT_INSN(),
8596
8597 /* subprog 2 */
8598 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8599 /* lookup from map */
8600 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8601 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8603 BPF_LD_MAP_FD(BPF_REG_1, 0),
8604 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8605 BPF_FUNC_map_lookup_elem),
8606 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8607 BPF_MOV64_IMM(BPF_REG_0, 0),
8608 BPF_EXIT_INSN(), /* return 0 */
8609 /* write map_value_ptr into stack frame of main prog */
8610 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8611 BPF_MOV64_IMM(BPF_REG_0, 1),
8612 BPF_EXIT_INSN(), /* return 1 */
8613 },
8614 .prog_type = BPF_PROG_TYPE_XDP,
8615 .fixup_map1 = { 23 },
8616 .result = ACCEPT,
8617 },
8618 {
8619 "calls: two calls that return map_value with incorrect bool check",
8620 .insns = {
8621 /* main prog */
8622 /* pass fp-16, fp-8 into a function */
8623 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8624 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8625 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8626 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8627 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8628 BPF_MOV64_IMM(BPF_REG_0, 0),
8629 BPF_EXIT_INSN(),
8630
8631 /* subprog 1 */
8632 /* call 3rd function twice */
8633 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8634 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8635 /* first time with fp-8 */
8636 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
8637 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
8638 /* fetch map_value_ptr from the stack of this function */
8639 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
8640 /* write into map value */
8641 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8642 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8643 /* second time with fp-16 */
8644 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
8645 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8646 /* fetch secound map_value_ptr from the stack */
8647 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
8648 /* write into map value */
8649 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8650 BPF_EXIT_INSN(),
8651
8652 /* subprog 2 */
8653 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8654 /* lookup from map */
8655 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8656 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8657 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8658 BPF_LD_MAP_FD(BPF_REG_1, 0),
8659 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8660 BPF_FUNC_map_lookup_elem),
8661 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8662 BPF_MOV64_IMM(BPF_REG_0, 0),
8663 BPF_EXIT_INSN(), /* return 0 */
8664 /* write map_value_ptr into stack frame of main prog */
8665 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8666 BPF_MOV64_IMM(BPF_REG_0, 1),
8667 BPF_EXIT_INSN(), /* return 1 */
8668 },
8669 .prog_type = BPF_PROG_TYPE_XDP,
8670 .fixup_map1 = { 23 },
8671 .result = REJECT,
8672 .errstr = "invalid read from stack off -16+0 size 8",
8673 },
8674 {
8675 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
8676 .insns = {
8677 /* main prog */
8678 /* pass fp-16, fp-8 into a function */
8679 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8680 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8681 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8682 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8683 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8684 BPF_MOV64_IMM(BPF_REG_0, 0),
8685 BPF_EXIT_INSN(),
8686
8687 /* subprog 1 */
8688 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8689 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8690 /* 1st lookup from map */
8691 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8692 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8693 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8694 BPF_LD_MAP_FD(BPF_REG_1, 0),
8695 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8696 BPF_FUNC_map_lookup_elem),
8697 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8698 BPF_MOV64_IMM(BPF_REG_8, 0),
8699 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8700 /* write map_value_ptr into stack frame of main prog at fp-8 */
8701 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8702 BPF_MOV64_IMM(BPF_REG_8, 1),
8703
8704 /* 2nd lookup from map */
8705 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
8706 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8707 BPF_LD_MAP_FD(BPF_REG_1, 0),
8708 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
8709 BPF_FUNC_map_lookup_elem),
8710 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8711 BPF_MOV64_IMM(BPF_REG_9, 0),
8712 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8713 /* write map_value_ptr into stack frame of main prog at fp-16 */
8714 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8715 BPF_MOV64_IMM(BPF_REG_9, 1),
8716
8717 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
8718 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
8719 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
8720 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
8721 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
8722 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
8723 BPF_EXIT_INSN(),
8724
8725 /* subprog 2 */
8726 /* if arg2 == 1 do *arg1 = 0 */
8727 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
8728 /* fetch map_value_ptr from the stack of this function */
8729 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
8730 /* write into map value */
8731 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8732
8733 /* if arg4 == 1 do *arg3 = 0 */
8734 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
8735 /* fetch map_value_ptr from the stack of this function */
8736 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
8737 /* write into map value */
8738 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
8739 BPF_EXIT_INSN(),
8740 },
8741 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8742 .fixup_map1 = { 12, 22 },
8743 .result = REJECT,
8744 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
8745 },
8746 {
8747 "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
8748 .insns = {
8749 /* main prog */
8750 /* pass fp-16, fp-8 into a function */
8751 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8752 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8753 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8754 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8755 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8756 BPF_MOV64_IMM(BPF_REG_0, 0),
8757 BPF_EXIT_INSN(),
8758
8759 /* subprog 1 */
8760 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8761 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8762 /* 1st lookup from map */
8763 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8764 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8765 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8766 BPF_LD_MAP_FD(BPF_REG_1, 0),
8767 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8768 BPF_FUNC_map_lookup_elem),
8769 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8770 BPF_MOV64_IMM(BPF_REG_8, 0),
8771 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8772 /* write map_value_ptr into stack frame of main prog at fp-8 */
8773 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8774 BPF_MOV64_IMM(BPF_REG_8, 1),
8775
8776 /* 2nd lookup from map */
8777 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
8778 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8779 BPF_LD_MAP_FD(BPF_REG_1, 0),
8780 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
8781 BPF_FUNC_map_lookup_elem),
8782 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8783 BPF_MOV64_IMM(BPF_REG_9, 0),
8784 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8785 /* write map_value_ptr into stack frame of main prog at fp-16 */
8786 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8787 BPF_MOV64_IMM(BPF_REG_9, 1),
8788
8789 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
8790 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
8791 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
8792 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
8793 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
8794 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */
8795 BPF_EXIT_INSN(),
8796
8797 /* subprog 2 */
8798 /* if arg2 == 1 do *arg1 = 0 */
8799 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
8800 /* fetch map_value_ptr from the stack of this function */
8801 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
8802 /* write into map value */
8803 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8804
8805 /* if arg4 == 1 do *arg3 = 0 */
8806 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
8807 /* fetch map_value_ptr from the stack of this function */
8808 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
8809 /* write into map value */
8810 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8811 BPF_EXIT_INSN(),
8812 },
8813 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8814 .fixup_map1 = { 12, 22 },
8815 .result = ACCEPT,
8816 },
8817 {
8818 "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
8819 .insns = {
8820 /* main prog */
8821 /* pass fp-16, fp-8 into a function */
8822 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8823 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8824 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8825 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8826 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
8827 BPF_MOV64_IMM(BPF_REG_0, 0),
8828 BPF_EXIT_INSN(),
8829
8830 /* subprog 1 */
8831 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8832 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8833 /* 1st lookup from map */
8834 BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
8835 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8836 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
8837 BPF_LD_MAP_FD(BPF_REG_1, 0),
8838 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8839 BPF_FUNC_map_lookup_elem),
8840 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8841 BPF_MOV64_IMM(BPF_REG_8, 0),
8842 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8843 /* write map_value_ptr into stack frame of main prog at fp-8 */
8844 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8845 BPF_MOV64_IMM(BPF_REG_8, 1),
8846
8847 /* 2nd lookup from map */
8848 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8849 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
8850 BPF_LD_MAP_FD(BPF_REG_1, 0),
8851 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8852 BPF_FUNC_map_lookup_elem),
8853 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8854 BPF_MOV64_IMM(BPF_REG_9, 0), // 26
8855 BPF_JMP_IMM(BPF_JA, 0, 0, 2),
8856 /* write map_value_ptr into stack frame of main prog at fp-16 */
8857 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8858 BPF_MOV64_IMM(BPF_REG_9, 1),
8859
8860 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
8861 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
8862 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
8863 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
8864 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
8865 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
8866 BPF_JMP_IMM(BPF_JA, 0, 0, -30),
8867
8868 /* subprog 2 */
8869 /* if arg2 == 1 do *arg1 = 0 */
8870 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
8871 /* fetch map_value_ptr from the stack of this function */
8872 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
8873 /* write into map value */
8874 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8875
8876 /* if arg4 == 1 do *arg3 = 0 */
8877 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
8878 /* fetch map_value_ptr from the stack of this function */
8879 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
8880 /* write into map value */
8881 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
8882 BPF_JMP_IMM(BPF_JA, 0, 0, -8),
8883 },
8884 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8885 .fixup_map1 = { 12, 22 },
8886 .result = REJECT,
8887 .errstr = "invalid access to map value, value_size=8 off=2 size=8",
8888 },
8889 {
8890 "calls: two calls that receive map_value_ptr_or_null via arg. test1",
8891 .insns = {
8892 /* main prog */
8893 /* pass fp-16, fp-8 into a function */
8894 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8895 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8896 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8898 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8899 BPF_MOV64_IMM(BPF_REG_0, 0),
8900 BPF_EXIT_INSN(),
8901
8902 /* subprog 1 */
8903 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8904 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8905 /* 1st lookup from map */
8906 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8907 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8908 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8909 BPF_LD_MAP_FD(BPF_REG_1, 0),
8910 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8911 BPF_FUNC_map_lookup_elem),
8912 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
8913 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8914 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8915 BPF_MOV64_IMM(BPF_REG_8, 0),
8916 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8917 BPF_MOV64_IMM(BPF_REG_8, 1),
8918
8919 /* 2nd lookup from map */
8920 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8921 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8922 BPF_LD_MAP_FD(BPF_REG_1, 0),
8923 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8924 BPF_FUNC_map_lookup_elem),
8925 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
8926 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8927 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8928 BPF_MOV64_IMM(BPF_REG_9, 0),
8929 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8930 BPF_MOV64_IMM(BPF_REG_9, 1),
8931
8932 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
8933 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
8934 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
8935 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
8936 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
8937 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
8938 BPF_EXIT_INSN(),
8939
8940 /* subprog 2 */
8941 /* if arg2 == 1 do *arg1 = 0 */
8942 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
8943 /* fetch map_value_ptr from the stack of this function */
8944 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
8945 /* write into map value */
8946 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8947
8948 /* if arg4 == 1 do *arg3 = 0 */
8949 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
8950 /* fetch map_value_ptr from the stack of this function */
8951 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
8952 /* write into map value */
8953 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
8954 BPF_EXIT_INSN(),
8955 },
8956 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8957 .fixup_map1 = { 12, 22 },
8958 .result = ACCEPT,
8959 },
8960 {
8961 "calls: two calls that receive map_value_ptr_or_null via arg. test2",
8962 .insns = {
8963 /* main prog */
8964 /* pass fp-16, fp-8 into a function */
8965 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
8966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
8967 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8968 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
8969 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
8970 BPF_MOV64_IMM(BPF_REG_0, 0),
8971 BPF_EXIT_INSN(),
8972
8973 /* subprog 1 */
8974 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
8975 BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
8976 /* 1st lookup from map */
8977 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
8978 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8979 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8980 BPF_LD_MAP_FD(BPF_REG_1, 0),
8981 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8982 BPF_FUNC_map_lookup_elem),
8983 /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
8984 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
8985 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8986 BPF_MOV64_IMM(BPF_REG_8, 0),
8987 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
8988 BPF_MOV64_IMM(BPF_REG_8, 1),
8989
8990 /* 2nd lookup from map */
8991 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8992 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8993 BPF_LD_MAP_FD(BPF_REG_1, 0),
8994 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
8995 BPF_FUNC_map_lookup_elem),
8996 /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
8997 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8998 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
8999 BPF_MOV64_IMM(BPF_REG_9, 0),
9000 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
9001 BPF_MOV64_IMM(BPF_REG_9, 1),
9002
9003 /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
9004 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
9005 BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
9006 BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
9007 BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
9008 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9009 BPF_EXIT_INSN(),
9010
9011 /* subprog 2 */
9012 /* if arg2 == 1 do *arg1 = 0 */
9013 BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
9014 /* fetch map_value_ptr from the stack of this function */
9015 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
9016 /* write into map value */
9017 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9018
9019 /* if arg4 == 0 do *arg3 = 0 */
9020 BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
9021 /* fetch map_value_ptr from the stack of this function */
9022 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
9023 /* write into map value */
9024 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
9025 BPF_EXIT_INSN(),
9026 },
9027 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9028 .fixup_map1 = { 12, 22 },
9029 .result = REJECT,
9030 .errstr = "R0 invalid mem access 'inv'",
9031 },
9032 {
9033 "calls: pkt_ptr spill into caller stack",
9034 .insns = {
9035 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
9036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
9037 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
9038 BPF_EXIT_INSN(),
9039
9040 /* subprog 1 */
9041 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
9042 offsetof(struct __sk_buff, data)),
9043 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
9044 offsetof(struct __sk_buff, data_end)),
9045 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
9046 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
9047 /* spill unchecked pkt_ptr into stack of caller */
9048 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
9049 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
9050 /* now the pkt range is verified, read pkt_ptr from stack */
9051 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
9052 /* write 4 bytes into packet */
9053 BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
9054 BPF_EXIT_INSN(),
9055 },
9056 .result = ACCEPT,
9057 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9058 },
8100}; 9059};
8101 9060
8102static int probe_filter_length(const struct bpf_insn *fp) 9061static int probe_filter_length(const struct bpf_insn *fp)