bpf: fix off-by-one error in adjust_subprog_starts
commitafd5942408
upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1fd99ac175
commit
bddeb44981
@ -5283,7 +5283,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;
|
||||||
}
|
}
|
||||||
|
@ -12511,6 +12511,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)
|
||||||
|
Reference in New Issue
Block a user