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

Commit fdc15d38 authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by David S. Miller
Browse files

bpf: perf_event progs should only use preallocated maps



Make sure that BPF_PROG_TYPE_PERF_EVENT programs only use
preallocated hash maps, since doing memory allocation
in overflow_handler can crash depending on where nmi got triggered.

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0515e599
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -2511,6 +2511,20 @@ static int do_check(struct verifier_env *env)
	return 0;
}

static int check_map_prog_compatibility(struct bpf_map *map,
					struct bpf_prog *prog)

{
	if (prog->type == BPF_PROG_TYPE_PERF_EVENT &&
	    (map->map_type == BPF_MAP_TYPE_HASH ||
	     map->map_type == BPF_MAP_TYPE_PERCPU_HASH) &&
	    (map->map_flags & BPF_F_NO_PREALLOC)) {
		verbose("perf_event programs can only use preallocated hash map\n");
		return -EINVAL;
	}
	return 0;
}

/* look for pseudo eBPF instructions that access map FDs and
 * replace them with actual map pointers
 */
@@ -2518,7 +2532,7 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
{
	struct bpf_insn *insn = env->prog->insnsi;
	int insn_cnt = env->prog->len;
	int i, j;
	int i, j, err;

	for (i = 0; i < insn_cnt; i++, insn++) {
		if (BPF_CLASS(insn->code) == BPF_LDX &&
@@ -2562,6 +2576,12 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
				return PTR_ERR(map);
			}

			err = check_map_prog_compatibility(map, env->prog);
			if (err) {
				fdput(f);
				return err;
			}

			/* store map pointer inside BPF_LD_IMM64 instruction */
			insn[0].imm = (u32) (unsigned long) map;
			insn[1].imm = ((u64) (unsigned long) map) >> 32;