148729226SJakub Kicinski { 2c48e51c8SKumar Kartikeya Dwivedi "calls: invalid kfunc call not eliminated", 3c48e51c8SKumar Kartikeya Dwivedi .insns = { 4c48e51c8SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 5c48e51c8SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 1), 6c48e51c8SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 7c48e51c8SKumar Kartikeya Dwivedi }, 8c48e51c8SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_TRACEPOINT, 9c48e51c8SKumar Kartikeya Dwivedi .result = REJECT, 10c48e51c8SKumar Kartikeya Dwivedi .errstr = "invalid kernel function call not eliminated in verifier pass", 11c48e51c8SKumar Kartikeya Dwivedi }, 12c48e51c8SKumar Kartikeya Dwivedi { 13c48e51c8SKumar Kartikeya Dwivedi "calls: invalid kfunc call unreachable", 14c48e51c8SKumar Kartikeya Dwivedi .insns = { 15c48e51c8SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 1), 16c48e51c8SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 0, 2), 17c48e51c8SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 18c48e51c8SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 1), 19c48e51c8SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 20c48e51c8SKumar Kartikeya Dwivedi }, 21c48e51c8SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_TRACEPOINT, 22c48e51c8SKumar Kartikeya Dwivedi .result = ACCEPT, 23c48e51c8SKumar Kartikeya Dwivedi }, 24c48e51c8SKumar Kartikeya Dwivedi { 25c1ff181fSKumar Kartikeya Dwivedi "calls: invalid kfunc call: ptr_to_mem to struct with non-scalar", 26c1ff181fSKumar Kartikeya Dwivedi .insns = { 27c1ff181fSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 28c1ff181fSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 29c1ff181fSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 30c1ff181fSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 31c1ff181fSKumar Kartikeya Dwivedi }, 32c1ff181fSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 33c1ff181fSKumar Kartikeya Dwivedi .result = REJECT, 34c1ff181fSKumar Kartikeya Dwivedi .errstr = "arg#0 pointer type STRUCT prog_test_fail1 must point to scalar", 35c1ff181fSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 36c1ff181fSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_fail1", 2 }, 37c1ff181fSKumar Kartikeya Dwivedi }, 38c1ff181fSKumar Kartikeya Dwivedi }, 39c1ff181fSKumar Kartikeya Dwivedi { 40c1ff181fSKumar Kartikeya Dwivedi "calls: invalid kfunc call: ptr_to_mem to struct with nesting depth > 4", 41c1ff181fSKumar Kartikeya Dwivedi .insns = { 42c1ff181fSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 43c1ff181fSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 44c1ff181fSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 45c1ff181fSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 46c1ff181fSKumar Kartikeya Dwivedi }, 47c1ff181fSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 48c1ff181fSKumar Kartikeya Dwivedi .result = REJECT, 49c1ff181fSKumar Kartikeya Dwivedi .errstr = "max struct nesting depth exceeded\narg#0 pointer type STRUCT prog_test_fail2", 50c1ff181fSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 51c1ff181fSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_fail2", 2 }, 52c1ff181fSKumar Kartikeya Dwivedi }, 53c1ff181fSKumar Kartikeya Dwivedi }, 54c1ff181fSKumar Kartikeya Dwivedi { 55c1ff181fSKumar Kartikeya Dwivedi "calls: invalid kfunc call: ptr_to_mem to struct with FAM", 56c1ff181fSKumar Kartikeya Dwivedi .insns = { 57c1ff181fSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 58c1ff181fSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 59c1ff181fSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 60c1ff181fSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 61c1ff181fSKumar Kartikeya Dwivedi }, 62c1ff181fSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 63c1ff181fSKumar Kartikeya Dwivedi .result = REJECT, 64c1ff181fSKumar Kartikeya Dwivedi .errstr = "arg#0 pointer type STRUCT prog_test_fail3 must point to scalar", 65c1ff181fSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 66c1ff181fSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_fail3", 2 }, 67c1ff181fSKumar Kartikeya Dwivedi }, 68c1ff181fSKumar Kartikeya Dwivedi }, 69c1ff181fSKumar Kartikeya Dwivedi { 70c1ff181fSKumar Kartikeya Dwivedi "calls: invalid kfunc call: reg->type != PTR_TO_CTX", 71c1ff181fSKumar Kartikeya Dwivedi .insns = { 72c1ff181fSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 73c1ff181fSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 74c1ff181fSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 75c1ff181fSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 76c1ff181fSKumar Kartikeya Dwivedi }, 77c1ff181fSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 78c1ff181fSKumar Kartikeya Dwivedi .result = REJECT, 79*bee109b7SMaxim Mikityanskiy .errstr = "arg#0 expected pointer to ctx, but got fp", 80c1ff181fSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 81c1ff181fSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_pass_ctx", 2 }, 82c1ff181fSKumar Kartikeya Dwivedi }, 83c1ff181fSKumar Kartikeya Dwivedi }, 84c1ff181fSKumar Kartikeya Dwivedi { 85c1ff181fSKumar Kartikeya Dwivedi "calls: invalid kfunc call: void * not allowed in func proto without mem size arg", 86c1ff181fSKumar Kartikeya Dwivedi .insns = { 87c1ff181fSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 88c1ff181fSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 89c1ff181fSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 90c1ff181fSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 91c1ff181fSKumar Kartikeya Dwivedi }, 92c1ff181fSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 93c1ff181fSKumar Kartikeya Dwivedi .result = REJECT, 94c1ff181fSKumar Kartikeya Dwivedi .errstr = "arg#0 pointer type UNKNOWN must point to scalar", 95c1ff181fSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 96c1ff181fSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_mem_len_fail1", 2 }, 97c1ff181fSKumar Kartikeya Dwivedi }, 98c1ff181fSKumar Kartikeya Dwivedi }, 99c1ff181fSKumar Kartikeya Dwivedi { 10013c6a37dSKumar Kartikeya Dwivedi "calls: trigger reg2btf_ids[reg->type] for reg->type > __BPF_REG_TYPE_MAX", 10113c6a37dSKumar Kartikeya Dwivedi .insns = { 10213c6a37dSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 10313c6a37dSKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 10413c6a37dSKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 10513c6a37dSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 10613c6a37dSKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 10713c6a37dSKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 10813c6a37dSKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 10913c6a37dSKumar Kartikeya Dwivedi }, 11013c6a37dSKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 11113c6a37dSKumar Kartikeya Dwivedi .result = REJECT, 1126c831c46SDavid Vernet .errstr = "Possibly NULL pointer passed to trusted arg0", 11313c6a37dSKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 11413c6a37dSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 11513c6a37dSKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_release", 5 }, 11613c6a37dSKumar Kartikeya Dwivedi }, 11713c6a37dSKumar Kartikeya Dwivedi }, 11813c6a37dSKumar Kartikeya Dwivedi { 1198218ccb5SKumar Kartikeya Dwivedi "calls: invalid kfunc call: reg->off must be zero when passed to release kfunc", 1208218ccb5SKumar Kartikeya Dwivedi .insns = { 1218218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1228218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1238218ccb5SKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 1248218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1258218ccb5SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 1268218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 1278218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 1288218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1298218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1308218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 1318218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 1328218ccb5SKumar Kartikeya Dwivedi }, 1338218ccb5SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1348218ccb5SKumar Kartikeya Dwivedi .result = REJECT, 1358218ccb5SKumar Kartikeya Dwivedi .errstr = "R1 must have zero offset when passed to release func", 1368218ccb5SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 1378218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 1388218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_memb_release", 8 }, 1398218ccb5SKumar Kartikeya Dwivedi }, 1408218ccb5SKumar Kartikeya Dwivedi }, 1418218ccb5SKumar Kartikeya Dwivedi { 142792c0a34SKumar Kartikeya Dwivedi "calls: invalid kfunc call: don't match first member type when passed to release kfunc", 143792c0a34SKumar Kartikeya Dwivedi .insns = { 144792c0a34SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 145792c0a34SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 146792c0a34SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 147792c0a34SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 148792c0a34SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 149792c0a34SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 150792c0a34SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 151792c0a34SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 152792c0a34SKumar Kartikeya Dwivedi }, 153792c0a34SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 154792c0a34SKumar Kartikeya Dwivedi .result = REJECT, 155792c0a34SKumar Kartikeya Dwivedi .errstr = "kernel function bpf_kfunc_call_memb1_release args#0 expected pointer", 156792c0a34SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 157792c0a34SKumar Kartikeya Dwivedi { "bpf_kfunc_call_memb_acquire", 1 }, 158792c0a34SKumar Kartikeya Dwivedi { "bpf_kfunc_call_memb1_release", 5 }, 159792c0a34SKumar Kartikeya Dwivedi }, 160792c0a34SKumar Kartikeya Dwivedi }, 161792c0a34SKumar Kartikeya Dwivedi { 1628218ccb5SKumar Kartikeya Dwivedi "calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset", 1638218ccb5SKumar Kartikeya Dwivedi .insns = { 1648218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1658218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1668218ccb5SKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 1678218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1686c831c46SDavid Vernet BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 1698218ccb5SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 1708218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 1718218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 1728218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4), 1738218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1748218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 1756c831c46SDavid Vernet BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 1766c831c46SDavid Vernet BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1776c831c46SDavid Vernet BPF_MOV64_IMM(BPF_REG_0, 0), 1788218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 1798218ccb5SKumar Kartikeya Dwivedi }, 1808218ccb5SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 1818218ccb5SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 1828218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 1836c831c46SDavid Vernet { "bpf_kfunc_call_test_offset", 9 }, 1846c831c46SDavid Vernet { "bpf_kfunc_call_test_release", 12 }, 1858218ccb5SKumar Kartikeya Dwivedi }, 1868218ccb5SKumar Kartikeya Dwivedi .result_unpriv = REJECT, 1878218ccb5SKumar Kartikeya Dwivedi .result = REJECT, 1886fcd486bSAlexei Starovoitov .errstr = "ptr R1 off=-4 disallowed", 1898218ccb5SKumar Kartikeya Dwivedi }, 1908218ccb5SKumar Kartikeya Dwivedi { 1918218ccb5SKumar Kartikeya Dwivedi "calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset", 1928218ccb5SKumar Kartikeya Dwivedi .insns = { 1938218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 1948218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 1958218ccb5SKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 1968218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 1978218ccb5SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 1988218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 1998218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2008218ccb5SKumar Kartikeya Dwivedi BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4), 2018218ccb5SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3), 2028218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2038218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 2048218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2058218ccb5SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3), 2068218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2078218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 2088218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2098218ccb5SKumar Kartikeya Dwivedi BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 2108218ccb5SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2118218ccb5SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 2128218ccb5SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2138218ccb5SKumar Kartikeya Dwivedi }, 2148218ccb5SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2158218ccb5SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 2168218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 2178218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_release", 9 }, 2188218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_release", 13 }, 2198218ccb5SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_release", 17 }, 2208218ccb5SKumar Kartikeya Dwivedi }, 2218218ccb5SKumar Kartikeya Dwivedi .result_unpriv = REJECT, 2228218ccb5SKumar Kartikeya Dwivedi .result = REJECT, 2238218ccb5SKumar Kartikeya Dwivedi .errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed", 2248218ccb5SKumar Kartikeya Dwivedi }, 2258218ccb5SKumar Kartikeya Dwivedi { 2268dd5e756SKumar Kartikeya Dwivedi "calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID", 2278dd5e756SKumar Kartikeya Dwivedi .insns = { 2288dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 2298dd5e756SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 2308dd5e756SKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 2318dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2328dd5e756SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2338dd5e756SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2348dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 2358dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2368dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2378dd5e756SKumar Kartikeya Dwivedi BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 16), 2388dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2398dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 2408dd5e756SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2418dd5e756SKumar Kartikeya Dwivedi }, 2428dd5e756SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2438dd5e756SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 2448dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 2458dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_ref", 8 }, 2468dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_ref", 10 }, 2478dd5e756SKumar Kartikeya Dwivedi }, 2488dd5e756SKumar Kartikeya Dwivedi .result_unpriv = REJECT, 2498dd5e756SKumar Kartikeya Dwivedi .result = REJECT, 25020c09d92SAlexei Starovoitov .errstr = "R1 must be", 2518dd5e756SKumar Kartikeya Dwivedi }, 2528dd5e756SKumar Kartikeya Dwivedi { 2538dd5e756SKumar Kartikeya Dwivedi "calls: valid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID", 2548dd5e756SKumar Kartikeya Dwivedi .insns = { 2558dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 2568dd5e756SKumar Kartikeya Dwivedi BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 2578dd5e756SKumar Kartikeya Dwivedi BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 2588dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2598dd5e756SKumar Kartikeya Dwivedi BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 2608dd5e756SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2618dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 2628dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 2638dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2648dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 2658dd5e756SKumar Kartikeya Dwivedi BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 2668dd5e756SKumar Kartikeya Dwivedi BPF_MOV64_IMM(BPF_REG_0, 0), 2678dd5e756SKumar Kartikeya Dwivedi BPF_EXIT_INSN(), 2688dd5e756SKumar Kartikeya Dwivedi }, 2698dd5e756SKumar Kartikeya Dwivedi .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2708dd5e756SKumar Kartikeya Dwivedi .fixup_kfunc_btf_id = { 2718dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_acquire", 3 }, 2728dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_ref", 8 }, 2738dd5e756SKumar Kartikeya Dwivedi { "bpf_kfunc_call_test_release", 10 }, 2748dd5e756SKumar Kartikeya Dwivedi }, 2758dd5e756SKumar Kartikeya Dwivedi .result_unpriv = REJECT, 2768dd5e756SKumar Kartikeya Dwivedi .result = ACCEPT, 2778dd5e756SKumar Kartikeya Dwivedi }, 2788dd5e756SKumar Kartikeya Dwivedi { 279e435b043STengda Wu "calls: invalid kfunc call: must provide (attach_prog_fd, btf_id) pair when freplace", 280e435b043STengda Wu .insns = { 281e435b043STengda Wu BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), 282e435b043STengda Wu BPF_EXIT_INSN(), 283e435b043STengda Wu }, 284e435b043STengda Wu .prog_type = BPF_PROG_TYPE_EXT, 285e435b043STengda Wu .result = REJECT, 286e435b043STengda Wu .errstr = "Tracing programs must provide btf_id", 287e435b043STengda Wu .fixup_kfunc_btf_id = { 288e435b043STengda Wu { "bpf_dynptr_from_skb", 0 }, 289e435b043STengda Wu }, 290e435b043STengda Wu }, 291e435b043STengda Wu { 29248729226SJakub Kicinski "calls: basic sanity", 29348729226SJakub Kicinski .insns = { 29448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 29548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 29648729226SJakub Kicinski BPF_EXIT_INSN(), 29748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 29848729226SJakub Kicinski BPF_EXIT_INSN(), 29948729226SJakub Kicinski }, 30048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 30148729226SJakub Kicinski .result = ACCEPT, 30248729226SJakub Kicinski }, 30348729226SJakub Kicinski { 3042efcf695SColin Ian King "calls: not on unprivileged", 30548729226SJakub Kicinski .insns = { 30648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 30748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 30848729226SJakub Kicinski BPF_EXIT_INSN(), 30948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 31048729226SJakub Kicinski BPF_EXIT_INSN(), 31148729226SJakub Kicinski }, 312e6ac2450SMartin KaFai Lau .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 31348729226SJakub Kicinski .result_unpriv = REJECT, 31448729226SJakub Kicinski .result = ACCEPT, 31548729226SJakub Kicinski .retval = 1, 31648729226SJakub Kicinski }, 31748729226SJakub Kicinski { 31848729226SJakub Kicinski "calls: div by 0 in subprog", 31948729226SJakub Kicinski .insns = { 32048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 32148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 32248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 32348729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 32448729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 32548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 32648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 32748729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 32848729226SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 32948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 33048729226SJakub Kicinski BPF_EXIT_INSN(), 33148729226SJakub Kicinski BPF_MOV32_IMM(BPF_REG_2, 0), 33248729226SJakub Kicinski BPF_MOV32_IMM(BPF_REG_3, 1), 33348729226SJakub Kicinski BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2), 33448729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 33548729226SJakub Kicinski offsetof(struct __sk_buff, data)), 33648729226SJakub Kicinski BPF_EXIT_INSN(), 33748729226SJakub Kicinski }, 33848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 33948729226SJakub Kicinski .result = ACCEPT, 34048729226SJakub Kicinski .retval = 1, 34148729226SJakub Kicinski }, 34248729226SJakub Kicinski { 34348729226SJakub Kicinski "calls: multiple ret types in subprog 1", 34448729226SJakub Kicinski .insns = { 34548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 34648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 34748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 34848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 34948729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 35048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 35148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 35248729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 35348729226SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 35448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 35548729226SJakub Kicinski BPF_EXIT_INSN(), 35648729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 35748729226SJakub Kicinski offsetof(struct __sk_buff, data)), 35848729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 35948729226SJakub Kicinski BPF_MOV32_IMM(BPF_REG_0, 42), 36048729226SJakub Kicinski BPF_EXIT_INSN(), 36148729226SJakub Kicinski }, 36248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 36348729226SJakub Kicinski .result = REJECT, 3647df5072cSMykola Lysenko .errstr = "R0 invalid mem access 'scalar'", 36548729226SJakub Kicinski }, 36648729226SJakub Kicinski { 36748729226SJakub Kicinski "calls: multiple ret types in subprog 2", 36848729226SJakub Kicinski .insns = { 36948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 37048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 37148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 37248729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 37348729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 37448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), 37548729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 37648729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 37748729226SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), 37848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 37948729226SJakub Kicinski BPF_EXIT_INSN(), 38048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 38148729226SJakub Kicinski offsetof(struct __sk_buff, data)), 38248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 38348729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9), 38448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 38548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 38648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 38748729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 38848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 38948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 39048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 39148729226SJakub Kicinski offsetof(struct __sk_buff, data)), 39248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64), 39348729226SJakub Kicinski BPF_EXIT_INSN(), 39448729226SJakub Kicinski }, 39548729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 39648729226SJakub Kicinski .fixup_map_hash_8b = { 16 }, 39748729226SJakub Kicinski .result = REJECT, 398457f4436SAndrii Nakryiko .errstr = "R0 min value is outside of the allowed memory range", 39948729226SJakub Kicinski }, 40048729226SJakub Kicinski { 40148729226SJakub Kicinski "calls: overlapping caller/callee", 40248729226SJakub Kicinski .insns = { 40348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0), 40448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 40548729226SJakub Kicinski BPF_EXIT_INSN(), 40648729226SJakub Kicinski }, 40748729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 40848729226SJakub Kicinski .errstr = "last insn is not an exit or jmp", 40948729226SJakub Kicinski .result = REJECT, 41048729226SJakub Kicinski }, 41148729226SJakub Kicinski { 41248729226SJakub Kicinski "calls: wrong recursive calls", 41348729226SJakub Kicinski .insns = { 41448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 4), 41548729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 4), 41648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 41748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 41848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2), 41948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 42048729226SJakub Kicinski BPF_EXIT_INSN(), 42148729226SJakub Kicinski }, 42248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 42348729226SJakub Kicinski .errstr = "jump out of range", 42448729226SJakub Kicinski .result = REJECT, 42548729226SJakub Kicinski }, 42648729226SJakub Kicinski { 42748729226SJakub Kicinski "calls: wrong src reg", 42848729226SJakub Kicinski .insns = { 429e6ac2450SMartin KaFai Lau BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 3, 0, 0), 43048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 43148729226SJakub Kicinski BPF_EXIT_INSN(), 43248729226SJakub Kicinski }, 43348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 43448729226SJakub Kicinski .errstr = "BPF_CALL uses reserved fields", 43548729226SJakub Kicinski .result = REJECT, 43648729226SJakub Kicinski }, 43748729226SJakub Kicinski { 43848729226SJakub Kicinski "calls: wrong off value", 43948729226SJakub Kicinski .insns = { 44048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2), 44148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 44248729226SJakub Kicinski BPF_EXIT_INSN(), 44348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 44448729226SJakub Kicinski BPF_EXIT_INSN(), 44548729226SJakub Kicinski }, 44648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 44748729226SJakub Kicinski .errstr = "BPF_CALL uses reserved fields", 44848729226SJakub Kicinski .result = REJECT, 44948729226SJakub Kicinski }, 45048729226SJakub Kicinski { 45148729226SJakub Kicinski "calls: jump back loop", 45248729226SJakub Kicinski .insns = { 45348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1), 45448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 45548729226SJakub Kicinski BPF_EXIT_INSN(), 45648729226SJakub Kicinski }, 45748729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 45810e14e96SAndrii Nakryiko .errstr = "the call stack of 9 frames is too deep", 45948729226SJakub Kicinski .result = REJECT, 46048729226SJakub Kicinski }, 46148729226SJakub Kicinski { 46248729226SJakub Kicinski "calls: conditional call", 46348729226SJakub Kicinski .insns = { 46448729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 46548729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 46648729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 46748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 46848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 46948729226SJakub Kicinski BPF_EXIT_INSN(), 47048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 47148729226SJakub Kicinski BPF_EXIT_INSN(), 47248729226SJakub Kicinski }, 47348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 47448729226SJakub Kicinski .errstr = "jump out of range", 47548729226SJakub Kicinski .result = REJECT, 47648729226SJakub Kicinski }, 47748729226SJakub Kicinski { 47848729226SJakub Kicinski "calls: conditional call 2", 47948729226SJakub Kicinski .insns = { 48048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 48148729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 48248729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 48348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 48448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 48548729226SJakub Kicinski BPF_EXIT_INSN(), 48648729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 48748729226SJakub Kicinski BPF_EXIT_INSN(), 48848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 3), 48948729226SJakub Kicinski BPF_EXIT_INSN(), 49048729226SJakub Kicinski }, 49148729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 49248729226SJakub Kicinski .result = ACCEPT, 49348729226SJakub Kicinski }, 49448729226SJakub Kicinski { 49548729226SJakub Kicinski "calls: conditional call 3", 49648729226SJakub Kicinski .insns = { 49748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 49848729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 49948729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 50048729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 4), 50148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 50248729226SJakub Kicinski BPF_EXIT_INSN(), 50348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 50448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -6), 50548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 3), 50648729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -6), 50748729226SJakub Kicinski }, 508aeee380cSAlexei Starovoitov .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 509aeee380cSAlexei Starovoitov .errstr_unpriv = "back-edge from insn", 510aeee380cSAlexei Starovoitov .result_unpriv = REJECT, 511aeee380cSAlexei Starovoitov .result = ACCEPT, 512aeee380cSAlexei Starovoitov .retval = 1, 51348729226SJakub Kicinski }, 51448729226SJakub Kicinski { 51548729226SJakub Kicinski "calls: conditional call 4", 51648729226SJakub Kicinski .insns = { 51748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 51848729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 51948729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 52048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 52148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 52248729226SJakub Kicinski BPF_EXIT_INSN(), 52348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 52448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -5), 52548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 3), 52648729226SJakub Kicinski BPF_EXIT_INSN(), 52748729226SJakub Kicinski }, 52848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 52948729226SJakub Kicinski .result = ACCEPT, 53048729226SJakub Kicinski }, 53148729226SJakub Kicinski { 53248729226SJakub Kicinski "calls: conditional call 5", 53348729226SJakub Kicinski .insns = { 53448729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 53548729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 53648729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), 53748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 53848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 53948729226SJakub Kicinski BPF_EXIT_INSN(), 54048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 54148729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -6), 54248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 3), 54348729226SJakub Kicinski BPF_EXIT_INSN(), 54448729226SJakub Kicinski }, 545aeee380cSAlexei Starovoitov .prog_type = BPF_PROG_TYPE_SCHED_CLS, 546aeee380cSAlexei Starovoitov .result = ACCEPT, 547aeee380cSAlexei Starovoitov .retval = 1, 54848729226SJakub Kicinski }, 54948729226SJakub Kicinski { 55048729226SJakub Kicinski "calls: conditional call 6", 55148729226SJakub Kicinski .insns = { 552aeee380cSAlexei Starovoitov BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 553aeee380cSAlexei Starovoitov BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 55448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 555aeee380cSAlexei Starovoitov BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3), 55648729226SJakub Kicinski BPF_EXIT_INSN(), 55748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 55848729226SJakub Kicinski offsetof(struct __sk_buff, mark)), 55948729226SJakub Kicinski BPF_EXIT_INSN(), 56048729226SJakub Kicinski }, 561aeee380cSAlexei Starovoitov .prog_type = BPF_PROG_TYPE_SCHED_CLS, 562aeee380cSAlexei Starovoitov .errstr = "infinite loop detected", 56348729226SJakub Kicinski .result = REJECT, 56448729226SJakub Kicinski }, 56548729226SJakub Kicinski { 56648729226SJakub Kicinski "calls: using r0 returned by callee", 56748729226SJakub Kicinski .insns = { 56848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 56948729226SJakub Kicinski BPF_EXIT_INSN(), 57048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 2), 57148729226SJakub Kicinski BPF_EXIT_INSN(), 57248729226SJakub Kicinski }, 57348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 57448729226SJakub Kicinski .result = ACCEPT, 57548729226SJakub Kicinski }, 57648729226SJakub Kicinski { 57748729226SJakub Kicinski "calls: using uninit r0 from callee", 57848729226SJakub Kicinski .insns = { 57948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 58048729226SJakub Kicinski BPF_EXIT_INSN(), 58148729226SJakub Kicinski BPF_EXIT_INSN(), 58248729226SJakub Kicinski }, 58348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 58448729226SJakub Kicinski .errstr = "!read_ok", 58548729226SJakub Kicinski .result = REJECT, 58648729226SJakub Kicinski }, 58748729226SJakub Kicinski { 58848729226SJakub Kicinski "calls: callee is using r1", 58948729226SJakub Kicinski .insns = { 59048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 59148729226SJakub Kicinski BPF_EXIT_INSN(), 59248729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 59348729226SJakub Kicinski offsetof(struct __sk_buff, len)), 59448729226SJakub Kicinski BPF_EXIT_INSN(), 59548729226SJakub Kicinski }, 59648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_ACT, 59748729226SJakub Kicinski .result = ACCEPT, 59848729226SJakub Kicinski .retval = TEST_DATA_LEN, 59948729226SJakub Kicinski }, 60048729226SJakub Kicinski { 60148729226SJakub Kicinski "calls: callee using args1", 60248729226SJakub Kicinski .insns = { 60348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 60448729226SJakub Kicinski BPF_EXIT_INSN(), 60548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 60648729226SJakub Kicinski BPF_EXIT_INSN(), 60748729226SJakub Kicinski }, 60881626001SAlexei Starovoitov .errstr_unpriv = "allowed for", 60948729226SJakub Kicinski .result_unpriv = REJECT, 61048729226SJakub Kicinski .result = ACCEPT, 61148729226SJakub Kicinski .retval = POINTER_VALUE, 61248729226SJakub Kicinski }, 61348729226SJakub Kicinski { 61448729226SJakub Kicinski "calls: callee using wrong args2", 61548729226SJakub Kicinski .insns = { 61648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 61748729226SJakub Kicinski BPF_EXIT_INSN(), 61848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 61948729226SJakub Kicinski BPF_EXIT_INSN(), 62048729226SJakub Kicinski }, 62148729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 62248729226SJakub Kicinski .errstr = "R2 !read_ok", 62348729226SJakub Kicinski .result = REJECT, 62448729226SJakub Kicinski }, 62548729226SJakub Kicinski { 62648729226SJakub Kicinski "calls: callee using two args", 62748729226SJakub Kicinski .insns = { 62848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 62948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, 63048729226SJakub Kicinski offsetof(struct __sk_buff, len)), 63148729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, 63248729226SJakub Kicinski offsetof(struct __sk_buff, len)), 63348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 63448729226SJakub Kicinski BPF_EXIT_INSN(), 63548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 63648729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 63748729226SJakub Kicinski BPF_EXIT_INSN(), 63848729226SJakub Kicinski }, 63981626001SAlexei Starovoitov .errstr_unpriv = "allowed for", 64048729226SJakub Kicinski .result_unpriv = REJECT, 64148729226SJakub Kicinski .result = ACCEPT, 64248729226SJakub Kicinski .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN, 64348729226SJakub Kicinski }, 64448729226SJakub Kicinski { 64548729226SJakub Kicinski "calls: callee changing pkt pointers", 64648729226SJakub Kicinski .insns = { 64748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct xdp_md, data)), 64848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 64948729226SJakub Kicinski offsetof(struct xdp_md, data_end)), 65048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_8, BPF_REG_6), 65148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8), 65248729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2), 65348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 65448729226SJakub Kicinski /* clear_all_pkt_pointers() has to walk all frames 65548729226SJakub Kicinski * to make sure that pkt pointers in the caller 65648729226SJakub Kicinski * are cleared when callee is calling a helper that 65748729226SJakub Kicinski * adjusts packet size 65848729226SJakub Kicinski */ 65948729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 66048729226SJakub Kicinski BPF_MOV32_IMM(BPF_REG_0, 0), 66148729226SJakub Kicinski BPF_EXIT_INSN(), 66248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_2, 0), 66348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_xdp_adjust_head), 66448729226SJakub Kicinski BPF_EXIT_INSN(), 66548729226SJakub Kicinski }, 66648729226SJakub Kicinski .result = REJECT, 6677df5072cSMykola Lysenko .errstr = "R6 invalid mem access 'scalar'", 66848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 66948729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 67048729226SJakub Kicinski }, 67148729226SJakub Kicinski { 6726dd7f140SPaul Chaignon "calls: ptr null check in subprog", 6736dd7f140SPaul Chaignon .insns = { 6746dd7f140SPaul Chaignon BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 6756dd7f140SPaul Chaignon BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 6766dd7f140SPaul Chaignon BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 6776dd7f140SPaul Chaignon BPF_LD_MAP_FD(BPF_REG_1, 0), 6786dd7f140SPaul Chaignon BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 6796dd7f140SPaul Chaignon BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 6806dd7f140SPaul Chaignon BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 6816dd7f140SPaul Chaignon BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 6826dd7f140SPaul Chaignon BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 6836dd7f140SPaul Chaignon BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), 6846dd7f140SPaul Chaignon BPF_EXIT_INSN(), 6856dd7f140SPaul Chaignon BPF_MOV64_IMM(BPF_REG_0, 0), 6866dd7f140SPaul Chaignon BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 6876dd7f140SPaul Chaignon BPF_MOV64_IMM(BPF_REG_0, 1), 6886dd7f140SPaul Chaignon BPF_EXIT_INSN(), 6896dd7f140SPaul Chaignon }, 690e6ac2450SMartin KaFai Lau .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 6916dd7f140SPaul Chaignon .fixup_map_hash_48b = { 3 }, 6926dd7f140SPaul Chaignon .result_unpriv = REJECT, 6936dd7f140SPaul Chaignon .result = ACCEPT, 6946dd7f140SPaul Chaignon .retval = 0, 6956dd7f140SPaul Chaignon }, 6966dd7f140SPaul Chaignon { 69748729226SJakub Kicinski "calls: two calls with args", 69848729226SJakub Kicinski .insns = { 69948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 70048729226SJakub Kicinski BPF_EXIT_INSN(), 70148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 70248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 70348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 70448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 70548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 70648729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 70748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 70848729226SJakub Kicinski BPF_EXIT_INSN(), 70948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 71048729226SJakub Kicinski offsetof(struct __sk_buff, len)), 71148729226SJakub Kicinski BPF_EXIT_INSN(), 71248729226SJakub Kicinski }, 71348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 71448729226SJakub Kicinski .result = ACCEPT, 71548729226SJakub Kicinski .retval = TEST_DATA_LEN + TEST_DATA_LEN, 71648729226SJakub Kicinski }, 71748729226SJakub Kicinski { 71848729226SJakub Kicinski "calls: calls with stack arith", 71948729226SJakub Kicinski .insns = { 72048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 72148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 72248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 72348729226SJakub Kicinski BPF_EXIT_INSN(), 72448729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 72548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 72648729226SJakub Kicinski BPF_EXIT_INSN(), 72748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), 72848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 42), 72948729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), 73048729226SJakub Kicinski BPF_EXIT_INSN(), 73148729226SJakub Kicinski }, 73248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 73348729226SJakub Kicinski .result = ACCEPT, 73448729226SJakub Kicinski .retval = 42, 73548729226SJakub Kicinski }, 73648729226SJakub Kicinski { 73748729226SJakub Kicinski "calls: calls with misaligned stack access", 73848729226SJakub Kicinski .insns = { 73948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 74048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63), 74148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 74248729226SJakub Kicinski BPF_EXIT_INSN(), 74348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61), 74448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 74548729226SJakub Kicinski BPF_EXIT_INSN(), 74648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63), 74748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 42), 74848729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), 74948729226SJakub Kicinski BPF_EXIT_INSN(), 75048729226SJakub Kicinski }, 75148729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 75248729226SJakub Kicinski .flags = F_LOAD_WITH_STRICT_ALIGNMENT, 75348729226SJakub Kicinski .errstr = "misaligned stack access", 75448729226SJakub Kicinski .result = REJECT, 75548729226SJakub Kicinski }, 75648729226SJakub Kicinski { 75748729226SJakub Kicinski "calls: calls control flow, jump test", 75848729226SJakub Kicinski .insns = { 75948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 42), 76048729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 76148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 43), 76248729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 76348729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -3), 76448729226SJakub Kicinski BPF_EXIT_INSN(), 76548729226SJakub Kicinski }, 76648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 76748729226SJakub Kicinski .result = ACCEPT, 76848729226SJakub Kicinski .retval = 43, 76948729226SJakub Kicinski }, 77048729226SJakub Kicinski { 77148729226SJakub Kicinski "calls: calls control flow, jump test 2", 77248729226SJakub Kicinski .insns = { 77348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 42), 77448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 77548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 43), 77648729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 77748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3), 77848729226SJakub Kicinski BPF_EXIT_INSN(), 77948729226SJakub Kicinski }, 78048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 78148729226SJakub Kicinski .errstr = "jump out of range from insn 1 to 4", 78248729226SJakub Kicinski .result = REJECT, 78348729226SJakub Kicinski }, 78448729226SJakub Kicinski { 78548729226SJakub Kicinski "calls: two calls with bad jump", 78648729226SJakub Kicinski .insns = { 78748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 78848729226SJakub Kicinski BPF_EXIT_INSN(), 78948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 79048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 79148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 79248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 79348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 79448729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 79548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 79648729226SJakub Kicinski BPF_EXIT_INSN(), 79748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 79848729226SJakub Kicinski offsetof(struct __sk_buff, len)), 79948729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3), 80048729226SJakub Kicinski BPF_EXIT_INSN(), 80148729226SJakub Kicinski }, 80248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 80348729226SJakub Kicinski .errstr = "jump out of range from insn 11 to 9", 80448729226SJakub Kicinski .result = REJECT, 80548729226SJakub Kicinski }, 80648729226SJakub Kicinski { 80748729226SJakub Kicinski "calls: recursive call. test1", 80848729226SJakub Kicinski .insns = { 80948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 81048729226SJakub Kicinski BPF_EXIT_INSN(), 81148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1), 81248729226SJakub Kicinski BPF_EXIT_INSN(), 81348729226SJakub Kicinski }, 81448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 81510e14e96SAndrii Nakryiko .errstr = "the call stack of 9 frames is too deep", 81648729226SJakub Kicinski .result = REJECT, 81748729226SJakub Kicinski }, 81848729226SJakub Kicinski { 81948729226SJakub Kicinski "calls: recursive call. test2", 82048729226SJakub Kicinski .insns = { 82148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 82248729226SJakub Kicinski BPF_EXIT_INSN(), 82348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3), 82448729226SJakub Kicinski BPF_EXIT_INSN(), 82548729226SJakub Kicinski }, 82648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 82710e14e96SAndrii Nakryiko .errstr = "the call stack of 9 frames is too deep", 82848729226SJakub Kicinski .result = REJECT, 82948729226SJakub Kicinski }, 83048729226SJakub Kicinski { 83148729226SJakub Kicinski "calls: unreachable code", 83248729226SJakub Kicinski .insns = { 83348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 83448729226SJakub Kicinski BPF_EXIT_INSN(), 83548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 83648729226SJakub Kicinski BPF_EXIT_INSN(), 83748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 83848729226SJakub Kicinski BPF_EXIT_INSN(), 83948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 84048729226SJakub Kicinski BPF_EXIT_INSN(), 84148729226SJakub Kicinski }, 84248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 84348729226SJakub Kicinski .errstr = "unreachable insn 6", 84448729226SJakub Kicinski .result = REJECT, 84548729226SJakub Kicinski }, 84648729226SJakub Kicinski { 84748729226SJakub Kicinski "calls: invalid call", 84848729226SJakub Kicinski .insns = { 84948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 85048729226SJakub Kicinski BPF_EXIT_INSN(), 85148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4), 85248729226SJakub Kicinski BPF_EXIT_INSN(), 85348729226SJakub Kicinski }, 85448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 85548729226SJakub Kicinski .errstr = "invalid destination", 85648729226SJakub Kicinski .result = REJECT, 85748729226SJakub Kicinski }, 85848729226SJakub Kicinski { 85948729226SJakub Kicinski "calls: invalid call 2", 86048729226SJakub Kicinski .insns = { 86148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 86248729226SJakub Kicinski BPF_EXIT_INSN(), 86348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff), 86448729226SJakub Kicinski BPF_EXIT_INSN(), 86548729226SJakub Kicinski }, 86648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 86748729226SJakub Kicinski .errstr = "invalid destination", 86848729226SJakub Kicinski .result = REJECT, 86948729226SJakub Kicinski }, 87048729226SJakub Kicinski { 87148729226SJakub Kicinski "calls: jumping across function bodies. test1", 87248729226SJakub Kicinski .insns = { 87348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 87448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 87548729226SJakub Kicinski BPF_EXIT_INSN(), 87648729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3), 87748729226SJakub Kicinski BPF_EXIT_INSN(), 87848729226SJakub Kicinski }, 87948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 88048729226SJakub Kicinski .errstr = "jump out of range", 88148729226SJakub Kicinski .result = REJECT, 88248729226SJakub Kicinski }, 88348729226SJakub Kicinski { 88448729226SJakub Kicinski "calls: jumping across function bodies. test2", 88548729226SJakub Kicinski .insns = { 88648729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 88748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 88848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 88948729226SJakub Kicinski BPF_EXIT_INSN(), 89048729226SJakub Kicinski BPF_EXIT_INSN(), 89148729226SJakub Kicinski }, 89248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 89348729226SJakub Kicinski .errstr = "jump out of range", 89448729226SJakub Kicinski .result = REJECT, 89548729226SJakub Kicinski }, 89648729226SJakub Kicinski { 89748729226SJakub Kicinski "calls: call without exit", 89848729226SJakub Kicinski .insns = { 89948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 90048729226SJakub Kicinski BPF_EXIT_INSN(), 90148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 90248729226SJakub Kicinski BPF_EXIT_INSN(), 90348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 90448729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2), 90548729226SJakub Kicinski }, 90648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 90748729226SJakub Kicinski .errstr = "not an exit", 90848729226SJakub Kicinski .result = REJECT, 90948729226SJakub Kicinski }, 91048729226SJakub Kicinski { 91148729226SJakub Kicinski "calls: call into middle of ld_imm64", 91248729226SJakub Kicinski .insns = { 91348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 91448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 91548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 91648729226SJakub Kicinski BPF_EXIT_INSN(), 91748729226SJakub Kicinski BPF_LD_IMM64(BPF_REG_0, 0), 91848729226SJakub Kicinski BPF_EXIT_INSN(), 91948729226SJakub Kicinski }, 92048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 92148729226SJakub Kicinski .errstr = "last insn", 92248729226SJakub Kicinski .result = REJECT, 92348729226SJakub Kicinski }, 92448729226SJakub Kicinski { 92548729226SJakub Kicinski "calls: call into middle of other call", 92648729226SJakub Kicinski .insns = { 92748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 92848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 92948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 93048729226SJakub Kicinski BPF_EXIT_INSN(), 93148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 93248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 93348729226SJakub Kicinski BPF_EXIT_INSN(), 93448729226SJakub Kicinski }, 93548729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 93648729226SJakub Kicinski .errstr = "last insn", 93748729226SJakub Kicinski .result = REJECT, 93848729226SJakub Kicinski }, 93948729226SJakub Kicinski { 94009b28d76SAlexei Starovoitov "calls: subprog call with ld_abs in main prog", 94148729226SJakub Kicinski .insns = { 94248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 94348729226SJakub Kicinski BPF_LD_ABS(BPF_B, 0), 94448729226SJakub Kicinski BPF_LD_ABS(BPF_H, 0), 94548729226SJakub Kicinski BPF_LD_ABS(BPF_W, 0), 94648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), 94709b28d76SAlexei Starovoitov BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 94848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 94948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_7), 95048729226SJakub Kicinski BPF_LD_ABS(BPF_B, 0), 95148729226SJakub Kicinski BPF_LD_ABS(BPF_H, 0), 95248729226SJakub Kicinski BPF_LD_ABS(BPF_W, 0), 95348729226SJakub Kicinski BPF_EXIT_INSN(), 95448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_2, 1), 95548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_3, 2), 95648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push), 95748729226SJakub Kicinski BPF_EXIT_INSN(), 95848729226SJakub Kicinski }, 95948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 96009b28d76SAlexei Starovoitov .result = ACCEPT, 96148729226SJakub Kicinski }, 96248729226SJakub Kicinski { 96348729226SJakub Kicinski "calls: two calls with bad fallthrough", 96448729226SJakub Kicinski .insns = { 96548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 96648729226SJakub Kicinski BPF_EXIT_INSN(), 96748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 96848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 96948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 97048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 97148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 97248729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 97348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 97448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_0), 97548729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 97648729226SJakub Kicinski offsetof(struct __sk_buff, len)), 97748729226SJakub Kicinski BPF_EXIT_INSN(), 97848729226SJakub Kicinski }, 97948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_TRACEPOINT, 98048729226SJakub Kicinski .errstr = "not an exit", 98148729226SJakub Kicinski .result = REJECT, 98248729226SJakub Kicinski }, 98348729226SJakub Kicinski { 98448729226SJakub Kicinski "calls: two calls with stack read", 98548729226SJakub Kicinski .insns = { 98648729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 98748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 98848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 98948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 99048729226SJakub Kicinski BPF_EXIT_INSN(), 99148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 99248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6), 99348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 99448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 99548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 99648729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0), 99748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_7), 99848729226SJakub Kicinski BPF_EXIT_INSN(), 99948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), 100048729226SJakub Kicinski BPF_EXIT_INSN(), 100148729226SJakub Kicinski }, 100248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 100348729226SJakub Kicinski .result = ACCEPT, 100448729226SJakub Kicinski }, 100548729226SJakub Kicinski { 100648729226SJakub Kicinski "calls: two calls with stack write", 100748729226SJakub Kicinski .insns = { 100848729226SJakub Kicinski /* main prog */ 100948729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 101048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 101148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 101248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 101348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 101448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 101548729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 101648729226SJakub Kicinski BPF_EXIT_INSN(), 101748729226SJakub Kicinski 101848729226SJakub Kicinski /* subprog 1 */ 101948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 102048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 102148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7), 102248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), 102348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 102448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 102548729226SJakub Kicinski BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0), 102648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_8), 102748729226SJakub Kicinski /* write into stack frame of main prog */ 102848729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 102948729226SJakub Kicinski BPF_EXIT_INSN(), 103048729226SJakub Kicinski 103148729226SJakub Kicinski /* subprog 2 */ 103248729226SJakub Kicinski /* read from stack frame of main prog */ 103348729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), 103448729226SJakub Kicinski BPF_EXIT_INSN(), 103548729226SJakub Kicinski }, 103648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 103748729226SJakub Kicinski .result = ACCEPT, 103848729226SJakub Kicinski }, 103948729226SJakub Kicinski { 104048729226SJakub Kicinski "calls: stack overflow using two frames (pre-call access)", 104148729226SJakub Kicinski .insns = { 104248729226SJakub Kicinski /* prog 1 */ 104348729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 104448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), 104548729226SJakub Kicinski BPF_EXIT_INSN(), 104648729226SJakub Kicinski 104748729226SJakub Kicinski /* prog 2 */ 104848729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 104948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 105048729226SJakub Kicinski BPF_EXIT_INSN(), 105148729226SJakub Kicinski }, 105248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 105348729226SJakub Kicinski .errstr = "combined stack size", 105448729226SJakub Kicinski .result = REJECT, 105548729226SJakub Kicinski }, 105648729226SJakub Kicinski { 105748729226SJakub Kicinski "calls: stack overflow using two frames (post-call access)", 105848729226SJakub Kicinski .insns = { 105948729226SJakub Kicinski /* prog 1 */ 106048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), 106148729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 106248729226SJakub Kicinski BPF_EXIT_INSN(), 106348729226SJakub Kicinski 106448729226SJakub Kicinski /* prog 2 */ 106548729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 106648729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 106748729226SJakub Kicinski BPF_EXIT_INSN(), 106848729226SJakub Kicinski }, 106948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 107048729226SJakub Kicinski .errstr = "combined stack size", 107148729226SJakub Kicinski .result = REJECT, 107248729226SJakub Kicinski }, 107348729226SJakub Kicinski { 107448729226SJakub Kicinski "calls: stack depth check using three frames. test1", 107548729226SJakub Kicinski .insns = { 107648729226SJakub Kicinski /* main */ 107748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 107848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */ 107948729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0), 108048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 108148729226SJakub Kicinski BPF_EXIT_INSN(), 108248729226SJakub Kicinski /* A */ 108348729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 108448729226SJakub Kicinski BPF_EXIT_INSN(), 108548729226SJakub Kicinski /* B */ 108648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */ 108748729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 108848729226SJakub Kicinski BPF_EXIT_INSN(), 108948729226SJakub Kicinski }, 109048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 109148729226SJakub Kicinski /* stack_main=32, stack_A=256, stack_B=64 109248729226SJakub Kicinski * and max(main+A, main+A+B) < 512 109348729226SJakub Kicinski */ 109448729226SJakub Kicinski .result = ACCEPT, 109548729226SJakub Kicinski }, 109648729226SJakub Kicinski { 109748729226SJakub Kicinski "calls: stack depth check using three frames. test2", 109848729226SJakub Kicinski .insns = { 109948729226SJakub Kicinski /* main */ 110048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 110148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */ 110248729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0), 110348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 110448729226SJakub Kicinski BPF_EXIT_INSN(), 110548729226SJakub Kicinski /* A */ 110648729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 110748729226SJakub Kicinski BPF_EXIT_INSN(), 110848729226SJakub Kicinski /* B */ 110948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */ 111048729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 111148729226SJakub Kicinski BPF_EXIT_INSN(), 111248729226SJakub Kicinski }, 111348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 111448729226SJakub Kicinski /* stack_main=32, stack_A=64, stack_B=256 111548729226SJakub Kicinski * and max(main+A, main+A+B) < 512 111648729226SJakub Kicinski */ 111748729226SJakub Kicinski .result = ACCEPT, 111848729226SJakub Kicinski }, 111948729226SJakub Kicinski { 112048729226SJakub Kicinski "calls: stack depth check using three frames. test3", 112148729226SJakub Kicinski .insns = { 112248729226SJakub Kicinski /* main */ 112348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 112448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 112548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 112648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */ 112748729226SJakub Kicinski BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1), 112848729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0), 112948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 113048729226SJakub Kicinski BPF_EXIT_INSN(), 113148729226SJakub Kicinski /* A */ 113248729226SJakub Kicinski BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1), 113348729226SJakub Kicinski BPF_EXIT_INSN(), 113448729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0), 113548729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -3), 113648729226SJakub Kicinski /* B */ 113748729226SJakub Kicinski BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1), 113848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */ 113948729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0), 114048729226SJakub Kicinski BPF_EXIT_INSN(), 114148729226SJakub Kicinski }, 114248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 114348729226SJakub Kicinski /* stack_main=64, stack_A=224, stack_B=256 114448729226SJakub Kicinski * and max(main+A, main+A+B) > 512 114548729226SJakub Kicinski */ 114648729226SJakub Kicinski .errstr = "combined stack", 114748729226SJakub Kicinski .result = REJECT, 114848729226SJakub Kicinski }, 114948729226SJakub Kicinski { 115048729226SJakub Kicinski "calls: stack depth check using three frames. test4", 115148729226SJakub Kicinski /* void main(void) { 115248729226SJakub Kicinski * func1(0); 115348729226SJakub Kicinski * func1(1); 115448729226SJakub Kicinski * func2(1); 115548729226SJakub Kicinski * } 115648729226SJakub Kicinski * void func1(int alloc_or_recurse) { 115748729226SJakub Kicinski * if (alloc_or_recurse) { 115848729226SJakub Kicinski * frame_pointer[-300] = 1; 115948729226SJakub Kicinski * } else { 116048729226SJakub Kicinski * func2(alloc_or_recurse); 116148729226SJakub Kicinski * } 116248729226SJakub Kicinski * } 116348729226SJakub Kicinski * void func2(int alloc_or_recurse) { 116448729226SJakub Kicinski * if (alloc_or_recurse) { 116548729226SJakub Kicinski * frame_pointer[-300] = 1; 116648729226SJakub Kicinski * } 116748729226SJakub Kicinski * } 116848729226SJakub Kicinski */ 116948729226SJakub Kicinski .insns = { 117048729226SJakub Kicinski /* main */ 117148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_1, 0), 117248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */ 117348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_1, 1), 117448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */ 117548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_1, 1), 117648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */ 117748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 117848729226SJakub Kicinski BPF_EXIT_INSN(), 117948729226SJakub Kicinski /* A */ 118048729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2), 118148729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 118248729226SJakub Kicinski BPF_EXIT_INSN(), 118348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 118448729226SJakub Kicinski BPF_EXIT_INSN(), 118548729226SJakub Kicinski /* B */ 118648729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 118748729226SJakub Kicinski BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0), 118848729226SJakub Kicinski BPF_EXIT_INSN(), 118948729226SJakub Kicinski }, 119048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 119148729226SJakub Kicinski .result = REJECT, 119248729226SJakub Kicinski .errstr = "combined stack", 119348729226SJakub Kicinski }, 119448729226SJakub Kicinski { 119548729226SJakub Kicinski "calls: stack depth check using three frames. test5", 119648729226SJakub Kicinski .insns = { 119748729226SJakub Kicinski /* main */ 119848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 119948729226SJakub Kicinski BPF_EXIT_INSN(), 120048729226SJakub Kicinski /* A */ 120148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */ 120248729226SJakub Kicinski BPF_EXIT_INSN(), 120348729226SJakub Kicinski /* B */ 120448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 120548729226SJakub Kicinski BPF_EXIT_INSN(), 120648729226SJakub Kicinski /* C */ 120748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 120848729226SJakub Kicinski BPF_EXIT_INSN(), 120948729226SJakub Kicinski /* D */ 121048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 121148729226SJakub Kicinski BPF_EXIT_INSN(), 121248729226SJakub Kicinski /* E */ 121348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 121448729226SJakub Kicinski BPF_EXIT_INSN(), 121548729226SJakub Kicinski /* F */ 121648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 121748729226SJakub Kicinski BPF_EXIT_INSN(), 121848729226SJakub Kicinski /* G */ 121948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 122048729226SJakub Kicinski BPF_EXIT_INSN(), 122148729226SJakub Kicinski /* H */ 122248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 122348729226SJakub Kicinski BPF_EXIT_INSN(), 122448729226SJakub Kicinski }, 122548729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 122648729226SJakub Kicinski .errstr = "call stack", 122748729226SJakub Kicinski .result = REJECT, 122848729226SJakub Kicinski }, 122948729226SJakub Kicinski { 1230cabacfbbSPaul Chaignon "calls: stack depth check in dead code", 1231cabacfbbSPaul Chaignon .insns = { 1232cabacfbbSPaul Chaignon /* main */ 1233cabacfbbSPaul Chaignon BPF_MOV64_IMM(BPF_REG_1, 0), 1234cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */ 1235cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1236cabacfbbSPaul Chaignon /* A */ 1237cabacfbbSPaul Chaignon BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 1238cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */ 1239cabacfbbSPaul Chaignon BPF_MOV64_IMM(BPF_REG_0, 0), 1240cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1241cabacfbbSPaul Chaignon /* B */ 1242cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */ 1243cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1244cabacfbbSPaul Chaignon /* C */ 1245cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */ 1246cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1247cabacfbbSPaul Chaignon /* D */ 1248cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */ 1249cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1250cabacfbbSPaul Chaignon /* E */ 1251cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */ 1252cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1253cabacfbbSPaul Chaignon /* F */ 1254cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */ 1255cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1256cabacfbbSPaul Chaignon /* G */ 1257cabacfbbSPaul Chaignon BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */ 1258cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1259cabacfbbSPaul Chaignon /* H */ 1260cabacfbbSPaul Chaignon BPF_MOV64_IMM(BPF_REG_0, 0), 1261cabacfbbSPaul Chaignon BPF_EXIT_INSN(), 1262cabacfbbSPaul Chaignon }, 1263cabacfbbSPaul Chaignon .prog_type = BPF_PROG_TYPE_XDP, 1264cabacfbbSPaul Chaignon .errstr = "call stack", 1265cabacfbbSPaul Chaignon .result = REJECT, 1266cabacfbbSPaul Chaignon }, 1267cabacfbbSPaul Chaignon { 126848729226SJakub Kicinski "calls: spill into caller stack frame", 126948729226SJakub Kicinski .insns = { 127048729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 127148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 127248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 127348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 127448729226SJakub Kicinski BPF_EXIT_INSN(), 127548729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), 127648729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 127748729226SJakub Kicinski BPF_EXIT_INSN(), 127848729226SJakub Kicinski }, 127948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 128048729226SJakub Kicinski .errstr = "cannot spill", 128148729226SJakub Kicinski .result = REJECT, 128248729226SJakub Kicinski }, 128348729226SJakub Kicinski { 128448729226SJakub Kicinski "calls: write into caller stack frame", 128548729226SJakub Kicinski .insns = { 128648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 128748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 128848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 128948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 129048729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 129148729226SJakub Kicinski BPF_EXIT_INSN(), 129248729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42), 129348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 129448729226SJakub Kicinski BPF_EXIT_INSN(), 129548729226SJakub Kicinski }, 129648729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 129748729226SJakub Kicinski .result = ACCEPT, 129848729226SJakub Kicinski .retval = 42, 129948729226SJakub Kicinski }, 130048729226SJakub Kicinski { 130148729226SJakub Kicinski "calls: write into callee stack frame", 130248729226SJakub Kicinski .insns = { 130348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 130448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), 130548729226SJakub Kicinski BPF_EXIT_INSN(), 130648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), 130748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8), 130848729226SJakub Kicinski BPF_EXIT_INSN(), 130948729226SJakub Kicinski }, 131048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 131148729226SJakub Kicinski .errstr = "cannot return stack pointer", 131248729226SJakub Kicinski .result = REJECT, 131348729226SJakub Kicinski }, 131448729226SJakub Kicinski { 131548729226SJakub Kicinski "calls: two calls with stack write and void return", 131648729226SJakub Kicinski .insns = { 131748729226SJakub Kicinski /* main prog */ 131848729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 131948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 132048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 132148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 132248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 132348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 132448729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 132548729226SJakub Kicinski BPF_EXIT_INSN(), 132648729226SJakub Kicinski 132748729226SJakub Kicinski /* subprog 1 */ 132848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 132948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 133048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 133148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 133248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 133348729226SJakub Kicinski BPF_EXIT_INSN(), 133448729226SJakub Kicinski 133548729226SJakub Kicinski /* subprog 2 */ 133648729226SJakub Kicinski /* write into stack frame of main prog */ 133748729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0), 133848729226SJakub Kicinski BPF_EXIT_INSN(), /* void return */ 133948729226SJakub Kicinski }, 134048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 134148729226SJakub Kicinski .result = ACCEPT, 134248729226SJakub Kicinski }, 134348729226SJakub Kicinski { 134448729226SJakub Kicinski "calls: ambiguous return value", 134548729226SJakub Kicinski .insns = { 134648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 134748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 134848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 134948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 135048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 135148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 135248729226SJakub Kicinski BPF_EXIT_INSN(), 135348729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 135448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 135548729226SJakub Kicinski BPF_EXIT_INSN(), 135648729226SJakub Kicinski }, 135781626001SAlexei Starovoitov .errstr_unpriv = "allowed for", 135848729226SJakub Kicinski .result_unpriv = REJECT, 135948729226SJakub Kicinski .errstr = "R0 !read_ok", 136048729226SJakub Kicinski .result = REJECT, 136148729226SJakub Kicinski }, 136248729226SJakub Kicinski { 136348729226SJakub Kicinski "calls: two calls that return map_value", 136448729226SJakub Kicinski .insns = { 136548729226SJakub Kicinski /* main prog */ 136648729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 136748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 136848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 136948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 137048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 137148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8), 137248729226SJakub Kicinski 137348729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 137448729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 137548729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 137648729226SJakub Kicinski /* write into map value */ 137748729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 137848729226SJakub Kicinski /* fetch secound map_value_ptr from the stack */ 137948729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16), 138048729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 138148729226SJakub Kicinski /* write into map value */ 138248729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 138348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 138448729226SJakub Kicinski BPF_EXIT_INSN(), 138548729226SJakub Kicinski 138648729226SJakub Kicinski /* subprog 1 */ 138748729226SJakub Kicinski /* call 3rd function twice */ 138848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 138948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 139048729226SJakub Kicinski /* first time with fp-8 */ 139148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 139248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 139348729226SJakub Kicinski /* second time with fp-16 */ 139448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 139548729226SJakub Kicinski BPF_EXIT_INSN(), 139648729226SJakub Kicinski 139748729226SJakub Kicinski /* subprog 2 */ 139848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 139948729226SJakub Kicinski /* lookup from map */ 140048729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 140148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 140248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 140348729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 140448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 140548729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog */ 140648729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 140748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 140848729226SJakub Kicinski BPF_EXIT_INSN(), /* return 0 */ 140948729226SJakub Kicinski }, 141048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 141148729226SJakub Kicinski .fixup_map_hash_8b = { 23 }, 141248729226SJakub Kicinski .result = ACCEPT, 141348729226SJakub Kicinski }, 141448729226SJakub Kicinski { 141548729226SJakub Kicinski "calls: two calls that return map_value with bool condition", 141648729226SJakub Kicinski .insns = { 141748729226SJakub Kicinski /* main prog */ 141848729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 141948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 142048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 142148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 142248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 142348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 142448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 142548729226SJakub Kicinski BPF_EXIT_INSN(), 142648729226SJakub Kicinski 142748729226SJakub Kicinski /* subprog 1 */ 142848729226SJakub Kicinski /* call 3rd function twice */ 142948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 143048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 143148729226SJakub Kicinski /* first time with fp-8 */ 143248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 143348729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 143448729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 143548729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 143648729226SJakub Kicinski /* write into map value */ 143748729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 143848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 143948729226SJakub Kicinski /* second time with fp-16 */ 144048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 144148729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 144248729226SJakub Kicinski /* fetch secound map_value_ptr from the stack */ 144348729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 144448729226SJakub Kicinski /* write into map value */ 144548729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 144648729226SJakub Kicinski BPF_EXIT_INSN(), 144748729226SJakub Kicinski 144848729226SJakub Kicinski /* subprog 2 */ 144948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 145048729226SJakub Kicinski /* lookup from map */ 145148729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 145248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 145348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 145448729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 145548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 145648729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 145748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 145848729226SJakub Kicinski BPF_EXIT_INSN(), /* return 0 */ 145948729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog */ 146048729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 146148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 146248729226SJakub Kicinski BPF_EXIT_INSN(), /* return 1 */ 146348729226SJakub Kicinski }, 146448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 146548729226SJakub Kicinski .fixup_map_hash_8b = { 23 }, 146648729226SJakub Kicinski .result = ACCEPT, 146748729226SJakub Kicinski }, 146848729226SJakub Kicinski { 146948729226SJakub Kicinski "calls: two calls that return map_value with incorrect bool check", 147048729226SJakub Kicinski .insns = { 147148729226SJakub Kicinski /* main prog */ 147248729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 147348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 147448729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 147548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 147648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 147748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 147848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 147948729226SJakub Kicinski BPF_EXIT_INSN(), 148048729226SJakub Kicinski 148148729226SJakub Kicinski /* subprog 1 */ 148248729226SJakub Kicinski /* call 3rd function twice */ 148348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 148448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 148548729226SJakub Kicinski /* first time with fp-8 */ 148648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9), 148748729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), 148848729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 148948729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0), 149048729226SJakub Kicinski /* write into map value */ 149148729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 149248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 149348729226SJakub Kicinski /* second time with fp-16 */ 149448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 149548729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 149648729226SJakub Kicinski /* fetch secound map_value_ptr from the stack */ 149748729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), 149848729226SJakub Kicinski /* write into map value */ 149948729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 150048729226SJakub Kicinski BPF_EXIT_INSN(), 150148729226SJakub Kicinski 150248729226SJakub Kicinski /* subprog 2 */ 150348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 150448729226SJakub Kicinski /* lookup from map */ 150548729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 150648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 150748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 150848729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 150948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 151048729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 151148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 151248729226SJakub Kicinski BPF_EXIT_INSN(), /* return 0 */ 151348729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog */ 151448729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 151548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 1), 151648729226SJakub Kicinski BPF_EXIT_INSN(), /* return 1 */ 151748729226SJakub Kicinski }, 151848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 151948729226SJakub Kicinski .fixup_map_hash_8b = { 23 }, 152048729226SJakub Kicinski .result = REJECT, 15216b4a64baSAndrei Matei .errstr = "R0 invalid mem access 'scalar'", 15226b4a64baSAndrei Matei .result_unpriv = REJECT, 15236b4a64baSAndrei Matei .errstr_unpriv = "invalid read from stack R7 off=-16 size=8", 152448729226SJakub Kicinski }, 152548729226SJakub Kicinski { 152648729226SJakub Kicinski "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1", 152748729226SJakub Kicinski .insns = { 152848729226SJakub Kicinski /* main prog */ 152948729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 153048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 153148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 153248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 153348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 153448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 153548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 153648729226SJakub Kicinski BPF_EXIT_INSN(), 153748729226SJakub Kicinski 153848729226SJakub Kicinski /* subprog 1 */ 153948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 154048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 154148729226SJakub Kicinski /* 1st lookup from map */ 154248729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 154348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 154448729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 154548729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 154648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 154748729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 154848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 154948729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 155048729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-8 */ 155148729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 155248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 155348729226SJakub Kicinski 155448729226SJakub Kicinski /* 2nd lookup from map */ 155548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 155648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 155748729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 155848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 155948729226SJakub Kicinski BPF_FUNC_map_lookup_elem), 156048729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 156148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), 156248729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 156348729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-16 */ 156448729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 156548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 156648729226SJakub Kicinski 156748729226SJakub Kicinski /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 156848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 156948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 157048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 157148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 157248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 157348729226SJakub Kicinski BPF_EXIT_INSN(), 157448729226SJakub Kicinski 157548729226SJakub Kicinski /* subprog 2 */ 157648729226SJakub Kicinski /* if arg2 == 1 do *arg1 = 0 */ 157748729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 157848729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 157948729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 158048729226SJakub Kicinski /* write into map value */ 158148729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 158248729226SJakub Kicinski 158348729226SJakub Kicinski /* if arg4 == 1 do *arg3 = 0 */ 158448729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 158548729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 158648729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 158748729226SJakub Kicinski /* write into map value */ 158848729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 158948729226SJakub Kicinski BPF_EXIT_INSN(), 159048729226SJakub Kicinski }, 159148729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 159248729226SJakub Kicinski .fixup_map_hash_8b = { 12, 22 }, 159348729226SJakub Kicinski .result = REJECT, 159448729226SJakub Kicinski .errstr = "invalid access to map value, value_size=8 off=2 size=8", 159548729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 159648729226SJakub Kicinski }, 159748729226SJakub Kicinski { 159848729226SJakub Kicinski "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2", 159948729226SJakub Kicinski .insns = { 160048729226SJakub Kicinski /* main prog */ 160148729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 160248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 160348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 160448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 160548729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 160648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 160748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 160848729226SJakub Kicinski BPF_EXIT_INSN(), 160948729226SJakub Kicinski 161048729226SJakub Kicinski /* subprog 1 */ 161148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 161248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 161348729226SJakub Kicinski /* 1st lookup from map */ 161448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 161548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 161648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 161748729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 161848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 161948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 162048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 162148729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 162248729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-8 */ 162348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 162448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 162548729226SJakub Kicinski 162648729226SJakub Kicinski /* 2nd lookup from map */ 162748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */ 162848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 162948729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 163048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */ 163148729226SJakub Kicinski BPF_FUNC_map_lookup_elem), 163248729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 163348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), 163448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 163548729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-16 */ 163648729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 163748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 163848729226SJakub Kicinski 163948729226SJakub Kicinski /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 164048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */ 164148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 164248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 164348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 164448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), /* 34 */ 164548729226SJakub Kicinski BPF_EXIT_INSN(), 164648729226SJakub Kicinski 164748729226SJakub Kicinski /* subprog 2 */ 164848729226SJakub Kicinski /* if arg2 == 1 do *arg1 = 0 */ 164948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 165048729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 165148729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 165248729226SJakub Kicinski /* write into map value */ 165348729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 165448729226SJakub Kicinski 165548729226SJakub Kicinski /* if arg4 == 1 do *arg3 = 0 */ 165648729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 165748729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 165848729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 165948729226SJakub Kicinski /* write into map value */ 166048729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 166148729226SJakub Kicinski BPF_EXIT_INSN(), 166248729226SJakub Kicinski }, 166348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 166448729226SJakub Kicinski .fixup_map_hash_8b = { 12, 22 }, 166548729226SJakub Kicinski .result = ACCEPT, 166648729226SJakub Kicinski }, 166748729226SJakub Kicinski { 166848729226SJakub Kicinski "calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3", 166948729226SJakub Kicinski .insns = { 167048729226SJakub Kicinski /* main prog */ 167148729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 167248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 167348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 167448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 167548729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 167648729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), 167748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 167848729226SJakub Kicinski BPF_EXIT_INSN(), 167948729226SJakub Kicinski 168048729226SJakub Kicinski /* subprog 1 */ 168148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 168248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 168348729226SJakub Kicinski /* 1st lookup from map */ 168448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0), 168548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 168648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 168748729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 168848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 168948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 169048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 169148729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 169248729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-8 */ 169348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 169448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 169548729226SJakub Kicinski 169648729226SJakub Kicinski /* 2nd lookup from map */ 169748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 169848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24), 169948729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 170048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 170148729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 170248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), // 26 170348729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 2), 170448729226SJakub Kicinski /* write map_value_ptr into stack frame of main prog at fp-16 */ 170548729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 170648729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 170748729226SJakub Kicinski 170848729226SJakub Kicinski /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 170948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30 171048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 171148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 171248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 171348729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34 171448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -30), 171548729226SJakub Kicinski 171648729226SJakub Kicinski /* subprog 2 */ 171748729226SJakub Kicinski /* if arg2 == 1 do *arg1 = 0 */ 171848729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 171948729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 172048729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 172148729226SJakub Kicinski /* write into map value */ 172248729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 172348729226SJakub Kicinski 172448729226SJakub Kicinski /* if arg4 == 1 do *arg3 = 0 */ 172548729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 172648729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 172748729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 172848729226SJakub Kicinski /* write into map value */ 172948729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0), 173048729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, -8), 173148729226SJakub Kicinski }, 173248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 173348729226SJakub Kicinski .fixup_map_hash_8b = { 12, 22 }, 173448729226SJakub Kicinski .result = REJECT, 173548729226SJakub Kicinski .errstr = "invalid access to map value, value_size=8 off=2 size=8", 173648729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 173748729226SJakub Kicinski }, 173848729226SJakub Kicinski { 173948729226SJakub Kicinski "calls: two calls that receive map_value_ptr_or_null via arg. test1", 174048729226SJakub Kicinski .insns = { 174148729226SJakub Kicinski /* main prog */ 174248729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 174348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 174448729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 174548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 174648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 174748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 174848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 174948729226SJakub Kicinski BPF_EXIT_INSN(), 175048729226SJakub Kicinski 175148729226SJakub Kicinski /* subprog 1 */ 175248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 175348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 175448729226SJakub Kicinski /* 1st lookup from map */ 175548729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 175648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 175748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 175848729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 175948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 176048729226SJakub Kicinski /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 176148729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 176248729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 176348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 176448729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 176548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 176648729226SJakub Kicinski 176748729226SJakub Kicinski /* 2nd lookup from map */ 176848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 176948729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 177048729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 177148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 177248729226SJakub Kicinski /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 177348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 177448729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 177548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), 177648729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 177748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 177848729226SJakub Kicinski 177948729226SJakub Kicinski /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 178048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 178148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 178248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 178348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 178448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 178548729226SJakub Kicinski BPF_EXIT_INSN(), 178648729226SJakub Kicinski 178748729226SJakub Kicinski /* subprog 2 */ 178848729226SJakub Kicinski /* if arg2 == 1 do *arg1 = 0 */ 178948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 179048729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 179148729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 179248729226SJakub Kicinski /* write into map value */ 179348729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 179448729226SJakub Kicinski 179548729226SJakub Kicinski /* if arg4 == 1 do *arg3 = 0 */ 179648729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2), 179748729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 179848729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 179948729226SJakub Kicinski /* write into map value */ 180048729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 180148729226SJakub Kicinski BPF_EXIT_INSN(), 180248729226SJakub Kicinski }, 180348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 180448729226SJakub Kicinski .fixup_map_hash_8b = { 12, 22 }, 180548729226SJakub Kicinski .result = ACCEPT, 180648729226SJakub Kicinski }, 180748729226SJakub Kicinski { 180848729226SJakub Kicinski "calls: two calls that receive map_value_ptr_or_null via arg. test2", 180948729226SJakub Kicinski .insns = { 181048729226SJakub Kicinski /* main prog */ 181148729226SJakub Kicinski /* pass fp-16, fp-8 into a function */ 181248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 181348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 181448729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 181548729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), 181648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 181748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 181848729226SJakub Kicinski BPF_EXIT_INSN(), 181948729226SJakub Kicinski 182048729226SJakub Kicinski /* subprog 1 */ 182148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 182248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_7, BPF_REG_2), 182348729226SJakub Kicinski /* 1st lookup from map */ 182448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 182548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 182648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 182748729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 182848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 182948729226SJakub Kicinski /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 183048729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 183148729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 183248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 183348729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 183448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 183548729226SJakub Kicinski 183648729226SJakub Kicinski /* 2nd lookup from map */ 183748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 183848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 183948729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 184048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 184148729226SJakub Kicinski /* write map_value_ptr_or_null into stack frame of main prog at fp-16 */ 184248729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 184348729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 184448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), 184548729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 1), 184648729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 184748729226SJakub Kicinski 184848729226SJakub Kicinski /* call 3rd func with fp-8, 0|1, fp-16, 0|1 */ 184948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 185048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_8), 185148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_3, BPF_REG_7), 185248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_9), 185348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 185448729226SJakub Kicinski BPF_EXIT_INSN(), 185548729226SJakub Kicinski 185648729226SJakub Kicinski /* subprog 2 */ 185748729226SJakub Kicinski /* if arg2 == 1 do *arg1 = 0 */ 185848729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2), 185948729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 186048729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), 186148729226SJakub Kicinski /* write into map value */ 186248729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 186348729226SJakub Kicinski 186448729226SJakub Kicinski /* if arg4 == 0 do *arg3 = 0 */ 186548729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2), 186648729226SJakub Kicinski /* fetch map_value_ptr from the stack of this function */ 186748729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), 186848729226SJakub Kicinski /* write into map value */ 186948729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), 187048729226SJakub Kicinski BPF_EXIT_INSN(), 187148729226SJakub Kicinski }, 187248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 187348729226SJakub Kicinski .fixup_map_hash_8b = { 12, 22 }, 187448729226SJakub Kicinski .result = REJECT, 18757df5072cSMykola Lysenko .errstr = "R0 invalid mem access 'scalar'", 187648729226SJakub Kicinski }, 187748729226SJakub Kicinski { 187848729226SJakub Kicinski "calls: pkt_ptr spill into caller stack", 187948729226SJakub Kicinski .insns = { 188048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 188148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 188248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), 188348729226SJakub Kicinski BPF_EXIT_INSN(), 188448729226SJakub Kicinski 188548729226SJakub Kicinski /* subprog 1 */ 188648729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 188748729226SJakub Kicinski offsetof(struct __sk_buff, data)), 188848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 188948729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 189048729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 189148729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 189248729226SJakub Kicinski /* spill unchecked pkt_ptr into stack of caller */ 189348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 189448729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 189548729226SJakub Kicinski /* now the pkt range is verified, read pkt_ptr from stack */ 189648729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 189748729226SJakub Kicinski /* write 4 bytes into packet */ 189848729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 189948729226SJakub Kicinski BPF_EXIT_INSN(), 190048729226SJakub Kicinski }, 190148729226SJakub Kicinski .result = ACCEPT, 190248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 190348729226SJakub Kicinski .retval = POINTER_VALUE, 190448729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 190548729226SJakub Kicinski }, 190648729226SJakub Kicinski { 190748729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 2", 190848729226SJakub Kicinski .insns = { 190948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 191048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 191148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 191248729226SJakub Kicinski /* Marking is still kept, but not in all cases safe. */ 191348729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 191448729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 191548729226SJakub Kicinski BPF_EXIT_INSN(), 191648729226SJakub Kicinski 191748729226SJakub Kicinski /* subprog 1 */ 191848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 191948729226SJakub Kicinski offsetof(struct __sk_buff, data)), 192048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 192148729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 192248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 192348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 192448729226SJakub Kicinski /* spill unchecked pkt_ptr into stack of caller */ 192548729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 192648729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 192748729226SJakub Kicinski /* now the pkt range is verified, read pkt_ptr from stack */ 192848729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 192948729226SJakub Kicinski /* write 4 bytes into packet */ 193048729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 193148729226SJakub Kicinski BPF_EXIT_INSN(), 193248729226SJakub Kicinski }, 193348729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 193448729226SJakub Kicinski .errstr = "invalid access to packet", 193548729226SJakub Kicinski .result = REJECT, 193648729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 193748729226SJakub Kicinski }, 193848729226SJakub Kicinski { 193948729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 3", 194048729226SJakub Kicinski .insns = { 194148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 194248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 194348729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 194448729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 194548729226SJakub Kicinski /* Marking is still kept and safe here. */ 194648729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 194748729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 194848729226SJakub Kicinski BPF_EXIT_INSN(), 194948729226SJakub Kicinski 195048729226SJakub Kicinski /* subprog 1 */ 195148729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 195248729226SJakub Kicinski offsetof(struct __sk_buff, data)), 195348729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 195448729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 195548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 195648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 195748729226SJakub Kicinski /* spill unchecked pkt_ptr into stack of caller */ 195848729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 195948729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 196048729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 196148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 196248729226SJakub Kicinski /* now the pkt range is verified, read pkt_ptr from stack */ 196348729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 196448729226SJakub Kicinski /* write 4 bytes into packet */ 196548729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 196648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 196748729226SJakub Kicinski BPF_EXIT_INSN(), 196848729226SJakub Kicinski }, 196948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 197048729226SJakub Kicinski .result = ACCEPT, 197148729226SJakub Kicinski .retval = 1, 197248729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 197348729226SJakub Kicinski }, 197448729226SJakub Kicinski { 197548729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 4", 197648729226SJakub Kicinski .insns = { 197748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 197848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 197948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 198048729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), 198148729226SJakub Kicinski /* Check marking propagated. */ 198248729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 198348729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0), 198448729226SJakub Kicinski BPF_EXIT_INSN(), 198548729226SJakub Kicinski 198648729226SJakub Kicinski /* subprog 1 */ 198748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 198848729226SJakub Kicinski offsetof(struct __sk_buff, data)), 198948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 199048729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 199148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 199248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 199348729226SJakub Kicinski /* spill unchecked pkt_ptr into stack of caller */ 199448729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 199548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 199648729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 199748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 199848729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 199948729226SJakub Kicinski /* write 4 bytes into packet */ 200048729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 200148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 200248729226SJakub Kicinski BPF_EXIT_INSN(), 200348729226SJakub Kicinski }, 200448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 200548729226SJakub Kicinski .result = ACCEPT, 200648729226SJakub Kicinski .retval = 1, 200748729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 200848729226SJakub Kicinski }, 200948729226SJakub Kicinski { 201048729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 5", 201148729226SJakub Kicinski .insns = { 201248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 201348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 201448729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0), 201548729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 201648729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 201748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 201848729226SJakub Kicinski BPF_EXIT_INSN(), 201948729226SJakub Kicinski 202048729226SJakub Kicinski /* subprog 1 */ 202148729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 202248729226SJakub Kicinski offsetof(struct __sk_buff, data)), 202348729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 202448729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 202548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 202648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 202748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 202848729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 202948729226SJakub Kicinski /* spill checked pkt_ptr into stack of caller */ 203048729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 203148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 203248729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 203348729226SJakub Kicinski /* write 4 bytes into packet */ 203448729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 203548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 203648729226SJakub Kicinski BPF_EXIT_INSN(), 203748729226SJakub Kicinski }, 203848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 203948729226SJakub Kicinski .errstr = "same insn cannot be used with different", 204048729226SJakub Kicinski .result = REJECT, 204148729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 204248729226SJakub Kicinski }, 204348729226SJakub Kicinski { 204448729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 6", 204548729226SJakub Kicinski .insns = { 204648729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 204748729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 204848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 204948729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 205048729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 205148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 205248729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 205348729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 205448729226SJakub Kicinski BPF_EXIT_INSN(), 205548729226SJakub Kicinski 205648729226SJakub Kicinski /* subprog 1 */ 205748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 205848729226SJakub Kicinski offsetof(struct __sk_buff, data)), 205948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 206048729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 206148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 206248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 206348729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 206448729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 206548729226SJakub Kicinski /* spill checked pkt_ptr into stack of caller */ 206648729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 206748729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 206848729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 206948729226SJakub Kicinski /* write 4 bytes into packet */ 207048729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 207148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 207248729226SJakub Kicinski BPF_EXIT_INSN(), 207348729226SJakub Kicinski }, 207448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 207548729226SJakub Kicinski .errstr = "R4 invalid mem access", 207648729226SJakub Kicinski .result = REJECT, 207748729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 207848729226SJakub Kicinski }, 207948729226SJakub Kicinski { 208048729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 7", 208148729226SJakub Kicinski .insns = { 208248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_2, 0), 208348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 208448729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 208548729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 208648729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 208748729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 208848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 208948729226SJakub Kicinski BPF_EXIT_INSN(), 209048729226SJakub Kicinski 209148729226SJakub Kicinski /* subprog 1 */ 209248729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 209348729226SJakub Kicinski offsetof(struct __sk_buff, data)), 209448729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 209548729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 209648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 209748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 209848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 209948729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 210048729226SJakub Kicinski /* spill checked pkt_ptr into stack of caller */ 210148729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 210248729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 210348729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 210448729226SJakub Kicinski /* write 4 bytes into packet */ 210548729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 210648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 210748729226SJakub Kicinski BPF_EXIT_INSN(), 210848729226SJakub Kicinski }, 210948729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 211048729226SJakub Kicinski .errstr = "R4 invalid mem access", 211148729226SJakub Kicinski .result = REJECT, 211248729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 211348729226SJakub Kicinski }, 211448729226SJakub Kicinski { 211548729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 8", 211648729226SJakub Kicinski .insns = { 211748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 211848729226SJakub Kicinski offsetof(struct __sk_buff, data)), 211948729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 212048729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 212148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 212248729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 212348729226SJakub Kicinski BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 212448729226SJakub Kicinski BPF_EXIT_INSN(), 212548729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 212648729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 212748729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 212848729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 212948729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 213048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 213148729226SJakub Kicinski BPF_EXIT_INSN(), 213248729226SJakub Kicinski 213348729226SJakub Kicinski /* subprog 1 */ 213448729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 213548729226SJakub Kicinski offsetof(struct __sk_buff, data)), 213648729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 213748729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 213848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 213948729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 214048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 214148729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 214248729226SJakub Kicinski /* spill checked pkt_ptr into stack of caller */ 214348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 214448729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 214548729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 214648729226SJakub Kicinski /* write 4 bytes into packet */ 214748729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 214848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 214948729226SJakub Kicinski BPF_EXIT_INSN(), 215048729226SJakub Kicinski }, 215148729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 215248729226SJakub Kicinski .result = ACCEPT, 215348729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 215448729226SJakub Kicinski }, 215548729226SJakub Kicinski { 215648729226SJakub Kicinski "calls: pkt_ptr spill into caller stack 9", 215748729226SJakub Kicinski .insns = { 215848729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 215948729226SJakub Kicinski offsetof(struct __sk_buff, data)), 216048729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 216148729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 216248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 216348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 216448729226SJakub Kicinski BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1), 216548729226SJakub Kicinski BPF_EXIT_INSN(), 216648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 216748729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 216848729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 216948729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), 217048729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 217148729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0), 217248729226SJakub Kicinski BPF_EXIT_INSN(), 217348729226SJakub Kicinski 217448729226SJakub Kicinski /* subprog 1 */ 217548729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 217648729226SJakub Kicinski offsetof(struct __sk_buff, data)), 217748729226SJakub Kicinski BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 217848729226SJakub Kicinski offsetof(struct __sk_buff, data_end)), 217948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 218048729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 218148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 0), 218248729226SJakub Kicinski /* spill unchecked pkt_ptr into stack of caller */ 218348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 218448729226SJakub Kicinski BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 218548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_5, 1), 218648729226SJakub Kicinski /* don't read back pkt_ptr from stack here */ 218748729226SJakub Kicinski /* write 4 bytes into packet */ 218848729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0), 218948729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_0, BPF_REG_5), 219048729226SJakub Kicinski BPF_EXIT_INSN(), 219148729226SJakub Kicinski }, 219248729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SCHED_CLS, 219348729226SJakub Kicinski .errstr = "invalid access to packet", 219448729226SJakub Kicinski .result = REJECT, 219548729226SJakub Kicinski .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 219648729226SJakub Kicinski }, 219748729226SJakub Kicinski { 219848729226SJakub Kicinski "calls: caller stack init to zero or map_value_or_null", 219948729226SJakub Kicinski .insns = { 220048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 220148729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 220248729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 220348729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 220448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 220548729226SJakub Kicinski /* fetch map_value_or_null or const_zero from stack */ 220648729226SJakub Kicinski BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 220748729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 220848729226SJakub Kicinski /* store into map_value */ 220948729226SJakub Kicinski BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0), 221048729226SJakub Kicinski BPF_EXIT_INSN(), 221148729226SJakub Kicinski 221248729226SJakub Kicinski /* subprog 1 */ 221348729226SJakub Kicinski /* if (ctx == 0) return; */ 221448729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8), 221548729226SJakub Kicinski /* else bpf_map_lookup() and *(fp - 8) = r0 */ 221648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 221748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 221848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 221948729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 222048729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 222148729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 222248729226SJakub Kicinski /* write map_value_ptr_or_null into stack frame of main prog at fp-8 */ 222348729226SJakub Kicinski BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0), 222448729226SJakub Kicinski BPF_EXIT_INSN(), 222548729226SJakub Kicinski }, 222648729226SJakub Kicinski .fixup_map_hash_8b = { 13 }, 222748729226SJakub Kicinski .result = ACCEPT, 222848729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_XDP, 222948729226SJakub Kicinski }, 223048729226SJakub Kicinski { 223148729226SJakub Kicinski "calls: stack init to zero and pruning", 223248729226SJakub Kicinski .insns = { 223348729226SJakub Kicinski /* first make allocated_stack 16 byte */ 223448729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 223548729226SJakub Kicinski /* now fork the execution such that the false branch 223648729226SJakub Kicinski * of JGT insn will be verified second and it skisp zero 223748729226SJakub Kicinski * init of fp-8 stack slot. If stack liveness marking 223848729226SJakub Kicinski * is missing live_read marks from call map_lookup 223948729226SJakub Kicinski * processing then pruning will incorrectly assume 224048729226SJakub Kicinski * that fp-8 stack slot was unused in the fall-through 224148729226SJakub Kicinski * branch and will accept the program incorrectly 224248729226SJakub Kicinski */ 22436715df8dSEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), 22446715df8dSEduard Zingerman BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2), 224548729226SJakub Kicinski BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 224648729226SJakub Kicinski BPF_JMP_IMM(BPF_JA, 0, 0, 0), 224748729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 224848729226SJakub Kicinski BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 224948729226SJakub Kicinski BPF_LD_MAP_FD(BPF_REG_1, 0), 225048729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 22516715df8dSEduard Zingerman BPF_MOV64_IMM(BPF_REG_0, 0), 225248729226SJakub Kicinski BPF_EXIT_INSN(), 225348729226SJakub Kicinski }, 22546715df8dSEduard Zingerman .fixup_map_hash_48b = { 7 }, 22556715df8dSEduard Zingerman .errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8", 22566715df8dSEduard Zingerman .result_unpriv = REJECT, 22576715df8dSEduard Zingerman /* in privileged mode reads from uninitialized stack locations are permitted */ 22586715df8dSEduard Zingerman .result = ACCEPT, 225948729226SJakub Kicinski }, 226048729226SJakub Kicinski { 226148729226SJakub Kicinski "calls: ctx read at start of subprog", 226248729226SJakub Kicinski .insns = { 226348729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 226448729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5), 226548729226SJakub Kicinski BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0), 226648729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 226748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 226848729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 226948729226SJakub Kicinski BPF_EXIT_INSN(), 227048729226SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 227148729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 227248729226SJakub Kicinski BPF_EXIT_INSN(), 227348729226SJakub Kicinski }, 227448729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2275e6ac2450SMartin KaFai Lau .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 227648729226SJakub Kicinski .result_unpriv = REJECT, 227748729226SJakub Kicinski .result = ACCEPT, 227848729226SJakub Kicinski }, 227948729226SJakub Kicinski { 228048729226SJakub Kicinski "calls: cross frame pruning", 228148729226SJakub Kicinski .insns = { 228248729226SJakub Kicinski /* r8 = !!random(); 228348729226SJakub Kicinski * call pruner() 228448729226SJakub Kicinski * if (r8) 228548729226SJakub Kicinski * do something bad; 228648729226SJakub Kicinski */ 228748729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 228848729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 228948729226SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 229048729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 229148729226SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), 229248729226SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 229348729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 229448729226SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0), 229548729226SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 229648729226SJakub Kicinski BPF_EXIT_INSN(), 229748729226SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 229848729226SJakub Kicinski BPF_EXIT_INSN(), 229948729226SJakub Kicinski }, 230048729226SJakub Kicinski .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2301e6ac2450SMartin KaFai Lau .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 230248729226SJakub Kicinski .errstr = "!read_ok", 230348729226SJakub Kicinski .result = REJECT, 230448729226SJakub Kicinski }, 230583d16312SJakub Kicinski { 230683d16312SJakub Kicinski "calls: cross frame pruning - liveness propagation", 230783d16312SJakub Kicinski .insns = { 230883d16312SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 230983d16312SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 0), 231083d16312SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 231183d16312SJakub Kicinski BPF_MOV64_IMM(BPF_REG_8, 1), 231283d16312SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), 231383d16312SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 0), 231483d16312SJakub Kicinski BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 231583d16312SJakub Kicinski BPF_MOV64_IMM(BPF_REG_9, 1), 231683d16312SJakub Kicinski BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 231783d16312SJakub Kicinski BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 231883d16312SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), 231983d16312SJakub Kicinski BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0), 232083d16312SJakub Kicinski BPF_MOV64_IMM(BPF_REG_0, 0), 232183d16312SJakub Kicinski BPF_EXIT_INSN(), 232283d16312SJakub Kicinski BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), 232383d16312SJakub Kicinski BPF_EXIT_INSN(), 232483d16312SJakub Kicinski }, 232583d16312SJakub Kicinski .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 2326e6ac2450SMartin KaFai Lau .errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for", 232783d16312SJakub Kicinski .errstr = "!read_ok", 232883d16312SJakub Kicinski .result = REJECT, 232983d16312SJakub Kicinski }, 23307d057943SEduard Zingerman /* Make sure that verifier.c:states_equal() considers IDs from all 23317d057943SEduard Zingerman * frames when building 'idmap' for check_ids(). 23327d057943SEduard Zingerman */ 23337d057943SEduard Zingerman { 23347d057943SEduard Zingerman "calls: check_ids() across call boundary", 23357d057943SEduard Zingerman .insns = { 23367d057943SEduard Zingerman /* Function main() */ 23377d057943SEduard Zingerman BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 23387d057943SEduard Zingerman /* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 23397d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 23407d057943SEduard Zingerman BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 23417d057943SEduard Zingerman BPF_LD_MAP_FD(BPF_REG_1, 23427d057943SEduard Zingerman 0), 23437d057943SEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 23447d057943SEduard Zingerman BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24), 23457d057943SEduard Zingerman /* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */ 23467d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 23477d057943SEduard Zingerman BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 23487d057943SEduard Zingerman BPF_LD_MAP_FD(BPF_REG_1, 23497d057943SEduard Zingerman 0), 23507d057943SEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 23517d057943SEduard Zingerman BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32), 23527d057943SEduard Zingerman /* call foo(&fp[-24], &fp[-32]) ; both arguments have IDs in the current 23537d057943SEduard Zingerman * ; stack frame 23547d057943SEduard Zingerman */ 23557d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP), 23567d057943SEduard Zingerman BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24), 23577d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), 23587d057943SEduard Zingerman BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32), 23597d057943SEduard Zingerman BPF_CALL_REL(2), 23607d057943SEduard Zingerman /* exit 0 */ 23617d057943SEduard Zingerman BPF_MOV64_IMM(BPF_REG_0, 0), 23627d057943SEduard Zingerman BPF_EXIT_INSN(), 23637d057943SEduard Zingerman /* Function foo() 23647d057943SEduard Zingerman * 23657d057943SEduard Zingerman * r9 = &frame[0].fp[-24] ; save arguments in the callee saved registers, 23667d057943SEduard Zingerman * r8 = &frame[0].fp[-32] ; arguments are pointers to pointers to map value 23677d057943SEduard Zingerman */ 23687d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_9, BPF_REG_1), 23697d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_8, BPF_REG_2), 23707d057943SEduard Zingerman /* r7 = ktime_get_ns() */ 23717d057943SEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 23727d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 23737d057943SEduard Zingerman /* r6 = ktime_get_ns() */ 23747d057943SEduard Zingerman BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 23757d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 23767d057943SEduard Zingerman /* if r6 > r7 goto +1 ; no new information about the state is derived from 23777d057943SEduard Zingerman * ; this check, thus produced verifier states differ 23787d057943SEduard Zingerman * ; only in 'insn_idx' 23797d057943SEduard Zingerman * r9 = r8 23807d057943SEduard Zingerman */ 23817d057943SEduard Zingerman BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), 23827d057943SEduard Zingerman BPF_MOV64_REG(BPF_REG_9, BPF_REG_8), 23837d057943SEduard Zingerman /* r9 = *r9 ; verifier get's to this point via two paths: 23847d057943SEduard Zingerman * ; (I) one including r9 = r8, verified first; 23857d057943SEduard Zingerman * ; (II) one excluding r9 = r8, verified next. 23867d057943SEduard Zingerman * ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id. 23877d057943SEduard Zingerman * ; Suppose that checkpoint is created here via path (I). 23887d057943SEduard Zingerman * ; When verifying via (II) the r9.id must be compared against 23897d057943SEduard Zingerman * ; frame[0].fp[-24].id, otherwise (I) and (II) would be 23907d057943SEduard Zingerman * ; incorrectly deemed equivalent. 23917d057943SEduard Zingerman * if r9 == 0 goto <exit> 23927d057943SEduard Zingerman */ 23937d057943SEduard Zingerman BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0), 23947d057943SEduard Zingerman BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1), 23957d057943SEduard Zingerman /* r8 = *r8 ; read map value via r8, this is not safe 23967d057943SEduard Zingerman * r0 = *r8 ; because r8 might be not equal to r9. 23977d057943SEduard Zingerman */ 23987d057943SEduard Zingerman BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0), 23997d057943SEduard Zingerman BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0), 24007d057943SEduard Zingerman /* exit 0 */ 24017d057943SEduard Zingerman BPF_MOV64_IMM(BPF_REG_0, 0), 24027d057943SEduard Zingerman BPF_EXIT_INSN(), 24037d057943SEduard Zingerman }, 24047d057943SEduard Zingerman .flags = BPF_F_TEST_STATE_FREQ, 24057d057943SEduard Zingerman .fixup_map_hash_8b = { 3, 9 }, 24067d057943SEduard Zingerman .result = REJECT, 24077d057943SEduard Zingerman .errstr = "R8 invalid mem access 'map_value_or_null'", 24087d057943SEduard Zingerman .result_unpriv = REJECT, 24097d057943SEduard Zingerman .errstr_unpriv = "", 24107d057943SEduard Zingerman .prog_type = BPF_PROG_TYPE_CGROUP_SKB, 24117d057943SEduard Zingerman }, 2412