mirror of https://gitee.com/openkylin/linux.git
bpf: fix off-by-one error in adjust_subprog_starts
When patching in a new sequence for the first insn of a subprog, the start
of that subprog does not change (it's the first insn of the sequence), so
adjust_subprog_starts should check start <= off (rather than < off).
Also added a test to test_verifier.c (it's essentially the syz reproducer).
Fixes: cc8b0b92a1
("bpf: introduce function calls (function boundaries)")
Reported-by: syzbot+4fc427c7af994b0948be@syzkaller.appspotmail.com
Signed-off-by: Edward Cree <ecree@solarflare.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
da85d8bfd1
commit
afd5942408
|
@ -5650,7 +5650,7 @@ static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len
|
||||||
return;
|
return;
|
||||||
/* NOTE: fake 'exit' subprog should be updated as well. */
|
/* NOTE: fake 'exit' subprog should be updated as well. */
|
||||||
for (i = 0; i <= env->subprog_cnt; i++) {
|
for (i = 0; i <= env->subprog_cnt; i++) {
|
||||||
if (env->subprog_info[i].start < off)
|
if (env->subprog_info[i].start <= off)
|
||||||
continue;
|
continue;
|
||||||
env->subprog_info[i].start += len - 1;
|
env->subprog_info[i].start += len - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13896,6 +13896,25 @@ static struct bpf_test tests[] = {
|
||||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||||
.result = ACCEPT,
|
.result = ACCEPT,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"calls: ctx read at start of subprog",
|
||||||
|
.insns = {
|
||||||
|
BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
|
||||||
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
|
||||||
|
BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
|
||||||
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
|
||||||
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
|
||||||
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
|
BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
|
||||||
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
|
},
|
||||||
|
.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
|
||||||
|
.errstr_unpriv = "function calls to other bpf functions are allowed for root only",
|
||||||
|
.result_unpriv = REJECT,
|
||||||
|
.result = ACCEPT,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int probe_filter_length(const struct bpf_insn *fp)
|
static int probe_filter_length(const struct bpf_insn *fp)
|
||||||
|
|
Loading…
Reference in New Issue