mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-09 23:34:42 +08:00
e1fad0ff46
check_ptr_off_reg only allows fixed offset to be set for PTR_TO_BTF_ID, where reg->off < 0 doesn't make sense. This would shift the pointer backwards, and fails later in btf_struct_ids_match or btf_struct_walk due to out of bounds access (since offset is interpreted as unsigned). Improve the verifier by rejecting this case by using a better error message for BPF helpers and kfunc, by putting a check inside the check_func_arg_reg_off function. Also, update existing verifier selftests to work with new error string. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20220304224645.3677453-4-memxor@gmail.com
137 lines
3.8 KiB
C
137 lines
3.8 KiB
C
{
|
|
"check deducing bounds from const, 1",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 0),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "R0 tried to subtract pointer from scalar",
|
|
.result = REJECT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 2",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
|
|
BPF_EXIT_INSN(),
|
|
BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 1, 1),
|
|
BPF_EXIT_INSN(),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.result_unpriv = REJECT,
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 3",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "R0 tried to subtract pointer from scalar",
|
|
.result = REJECT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 4",
|
|
.insns = {
|
|
BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
|
|
BPF_EXIT_INSN(),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
|
|
BPF_EXIT_INSN(),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_6, BPF_REG_0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R6 has pointer with unsupported alu operation",
|
|
.result_unpriv = REJECT,
|
|
.result = ACCEPT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 5",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "R0 tried to subtract pointer from scalar",
|
|
.result = REJECT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 6",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
|
|
BPF_EXIT_INSN(),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "R0 tried to subtract pointer from scalar",
|
|
.result = REJECT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 7",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, ~0),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
|
|
offsetof(struct __sk_buff, mark)),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "dereference of modified ctx ptr",
|
|
.result = REJECT,
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 8",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, ~0),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
|
|
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
|
|
offsetof(struct __sk_buff, mark)),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "negative offset ctx ptr R1 off=-1 disallowed",
|
|
.result = REJECT,
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 9",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 0),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr_unpriv = "R1 has pointer with unsupported alu operation",
|
|
.errstr = "R0 tried to subtract pointer from scalar",
|
|
.result = REJECT,
|
|
},
|
|
{
|
|
"check deducing bounds from const, 10",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 0),
|
|
/* Marks reg as unknown. */
|
|
BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0),
|
|
BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.errstr = "math between ctx pointer and register with unbounded min value is not allowed",
|
|
.result = REJECT,
|
|
},
|