2022-04-25 03:19:00 +05:30
|
|
|
/* Common tests */
|
|
|
|
{
|
|
|
|
"map_kptr: BPF_ST imm != 0",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "BPF_ST imm must be 0 when storing to kptr at off=0",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: size != bpf_size_to_bytes(BPF_DW)",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "kptr access size must be BPF_DW",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: map_value non-const var_off",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "kptr access cannot have variable offset",
|
2023-07-05 13:39:25 +02:00
|
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
2022-04-25 03:19:00 +05:30
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: bpf_kptr_xchg non-const var_off",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_2, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_3),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_kptr_xchg),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "R1 doesn't have constant offset. kptr has to be at the constant offset",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unaligned boundary load/store",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 7),
|
|
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "kptr access misaligned expected=0 off=7",
|
2023-07-05 13:39:25 +02:00
|
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
2022-04-25 03:19:00 +05:30
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: reject var_off != 0",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
|
|
|
|
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "variable untrusted_ptr_ access var_off=(0x0; 0x7) disallowed",
|
|
|
|
},
|
2024-09-05 19:03:05 +08:00
|
|
|
/* Tests for unreferenced PTR_TO_BTF_ID */
|
2022-04-25 03:19:00 +05:30
|
|
|
{
|
|
|
|
"map_kptr: unref: reject btf_struct_ids_match == false",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
|
|
|
|
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "invalid kptr access, R1 type=untrusted_ptr_prog_test_ref_kfunc expected=ptr_prog_test",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unref: loaded pointer marked as untrusted",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
|
|
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "R0 invalid mem access 'untrusted_ptr_or_null_'",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unref: correct in kernel type size",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
2022-05-12 01:16:52 +05:30
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 32),
|
2022-04-25 03:19:00 +05:30
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
2022-05-12 01:16:52 +05:30
|
|
|
.errstr = "access beyond struct prog_test_ref_kfunc at off 32 size 8",
|
2022-04-25 03:19:00 +05:30
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unref: inherit PTR_UNTRUSTED on struct walk",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 16),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_this_cpu_ptr),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "R1 type=untrusted_ptr_ expected=percpu_ptr_",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unref: no reference state created",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = ACCEPT,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: unref: bpf_kptr_xchg rejected",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_kptr_xchg),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "off=0 kptr isn't referenced kptr",
|
|
|
|
},
|
|
|
|
/* Tests for referenced PTR_TO_BTF_ID */
|
|
|
|
{
|
|
|
|
"map_kptr: ref: loaded pointer marked as untrusted",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_1, 0),
|
|
|
|
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 8),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_this_cpu_ptr),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
2023-03-02 20:14:43 -08:00
|
|
|
.errstr = "R1 type=rcu_ptr_or_null_ expected=percpu_ptr_",
|
2022-04-25 03:19:00 +05:30
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: ref: reject off != 0",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
|
|
|
|
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_kptr_xchg),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_kptr_xchg),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: ref: reference state created and released on xchg",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
|
|
|
|
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
|
|
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_kptr_xchg),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
bpf: verifier: Support eliding map lookup nullness
This commit allows progs to elide a null check on statically known map
lookup keys. In other words, if the verifier can statically prove that
the lookup will be in-bounds, allow the prog to drop the null check.
This is useful for two reasons:
1. Large numbers of nullness checks (especially when they cannot fail)
unnecessarily pushes prog towards BPF_COMPLEXITY_LIMIT_JMP_SEQ.
2. It forms a tighter contract between programmer and verifier.
For (1), bpftrace is starting to make heavier use of percpu scratch
maps. As a result, for user scripts with large number of unrolled loops,
we are starting to hit jump complexity verification errors. These
percpu lookups cannot fail anyways, as we only use static key values.
Eliding nullness probably results in less work for verifier as well.
For (2), percpu scratch maps are often used as a larger stack, as the
currrent stack is limited to 512 bytes. In these situations, it is
desirable for the programmer to express: "this lookup should never fail,
and if it does, it means I messed up the code". By omitting the null
check, the programmer can "ask" the verifier to double check the logic.
Tests also have to be updated in sync with these changes, as the
verifier is more efficient with this change. Notable, iters.c tests had
to be changed to use a map type that still requires null checks, as it's
exercising verifier tracking logic w.r.t iterators.
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Link: https://lore.kernel.org/r/68f3ea96ff3809a87e502a11a4bd30177fc5823e.1736886479.git.dxu@dxuuu.xyz
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2025-01-14 13:28:45 -07:00
|
|
|
.errstr = "Unreleased reference id=4 alloc_insn=20",
|
2022-04-25 03:19:00 +05:30
|
|
|
.fixup_kfunc_btf_id = {
|
|
|
|
{ "bpf_kfunc_call_test_acquire", 15 },
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: ref: reject STX",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, 0),
|
|
|
|
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "store to referenced kptr disallowed",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: ref: reject ST",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_0, 8, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "store to referenced kptr disallowed",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"map_kptr: reject helper access to kptr",
|
|
|
|
.insns = {
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
BPF_LD_MAP_FD(BPF_REG_6, 0),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
|
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
|
|
|
|
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
|
|
|
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
|
|
.fixup_map_kptr = { 1 },
|
|
|
|
.result = REJECT,
|
|
|
|
.errstr = "kptr cannot be accessed indirectly by helper",
|
|
|
|
},
|