Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bddeb449 authored by Edward Cree's avatar Edward Cree Committed by Greg Kroah-Hartman
Browse files

bpf: fix off-by-one error in adjust_subprog_starts



commit afd594240806acc138cf696c09f2f4829d55d02f 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: cc8b0b92 ("bpf: introduce function calls (function boundaries)")
Reported-by: default avatar <syzbot+4fc427c7af994b0948be@syzkaller.appspotmail.com>
Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1fd99ac1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5283,7 +5283,7 @@ static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len
		return;
	/* NOTE: fake 'exit' subprog should be updated as well. */
	for (i = 0; i <= env->subprog_cnt; i++) {
		if (env->subprog_info[i].start < off)
		if (env->subprog_info[i].start <= off)
			continue;
		env->subprog_info[i].start += len - 1;
	}
+19 −0
Original line number Diff line number Diff line
@@ -12511,6 +12511,25 @@ static struct bpf_test tests[] = {
		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
		.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)