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

Commit a06aef4e authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'bpf_func_info-improvements'



Martin KaFai Lau says:

====================
The patchset has a few improvements on bpf_func_info:
1. Improvements on the behaviors of info.func_info, info.func_info_cnt
   and info.func_info_rec_size.
2. Name change: s/insn_offset/insn_off/

Please see individual patch for details.
====================

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 30da46b5 84ecc1f9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2991,7 +2991,7 @@ struct bpf_flow_keys {
};

struct bpf_func_info {
	__u32	insn_offset;
	__u32	insn_off;
	__u32	type_id;
};

+1 −1
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ static void bpf_get_prog_name(const struct bpf_prog *prog, char *sym)
	sym  = bin2hex(sym, prog->tag, sizeof(prog->tag));

	/* prog->aux->name will be ignored if full btf name is available */
	if (prog->aux->btf) {
	if (prog->aux->func_info_cnt) {
		type = btf_type_by_id(prog->aux->btf,
				      prog->aux->func_info[prog->aux->func_idx].type_id);
		func_name = btf_name_by_offset(prog->aux->btf, type->name_off);
+20 −26
Original line number Diff line number Diff line
@@ -2083,6 +2083,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
				return -EFAULT;
	}

	if ((info.func_info_cnt || info.func_info_rec_size) &&
	    info.func_info_rec_size != sizeof(struct bpf_func_info))
		return -EINVAL;

	info.func_info_rec_size = sizeof(struct bpf_func_info);

	if (!capable(CAP_SYS_ADMIN)) {
		info.jited_prog_len = 0;
		info.xlated_prog_len = 0;
@@ -2226,35 +2232,23 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
		}
	}

	if (prog->aux->btf) {
		u32 krec_size = sizeof(struct bpf_func_info);
		u32 ucnt, urec_size;

	if (prog->aux->btf)
		info.btf_id = btf_id(prog->aux->btf);

		ucnt = info.func_info_cnt;
	ulen = info.func_info_cnt;
	info.func_info_cnt = prog->aux->func_info_cnt;
		urec_size = info.func_info_rec_size;
		info.func_info_rec_size = krec_size;
		if (ucnt) {
			/* expect passed-in urec_size is what the kernel expects */
			if (urec_size != info.func_info_rec_size)
				return -EINVAL;

	if (info.func_info_cnt && ulen) {
		if (bpf_dump_raw_ok()) {
			char __user *user_finfo;

			user_finfo = u64_to_user_ptr(info.func_info);
				ucnt = min_t(u32, info.func_info_cnt, ucnt);
			ulen = min_t(u32, info.func_info_cnt, ulen);
			if (copy_to_user(user_finfo, prog->aux->func_info,
						 krec_size * ucnt))
					 info.func_info_rec_size * ulen))
				return -EFAULT;
		} else {
				info.func_info_cnt = 0;
			}
			info.func_info = 0;
		}
	} else {
		info.func_info_cnt = 0;
	}

done:
+9 −9
Original line number Diff line number Diff line
@@ -4707,24 +4707,24 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
			goto free_btf;
		}

		/* check insn_offset */
		/* check insn_off */
		if (i == 0) {
			if (krecord[i].insn_offset) {
			if (krecord[i].insn_off) {
				verbose(env,
					"nonzero insn_offset %u for the first func info record",
					krecord[i].insn_offset);
					"nonzero insn_off %u for the first func info record",
					krecord[i].insn_off);
				ret = -EINVAL;
				goto free_btf;
			}
		} else if (krecord[i].insn_offset <= prev_offset) {
		} else if (krecord[i].insn_off <= prev_offset) {
			verbose(env,
				"same or smaller insn offset (%u) than previous func info record (%u)",
				krecord[i].insn_offset, prev_offset);
				krecord[i].insn_off, prev_offset);
			ret = -EINVAL;
			goto free_btf;
		}

		if (env->subprog_info[i].start != krecord[i].insn_offset) {
		if (env->subprog_info[i].start != krecord[i].insn_off) {
			verbose(env, "func_info BTF section doesn't match subprog layout in BPF program\n");
			ret = -EINVAL;
			goto free_btf;
@@ -4739,7 +4739,7 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
			goto free_btf;
		}

		prev_offset = krecord[i].insn_offset;
		prev_offset = krecord[i].insn_off;
		urecord += urec_size;
	}

@@ -4762,7 +4762,7 @@ static void adjust_btf_func(struct bpf_verifier_env *env)
		return;

	for (i = 0; i < env->subprog_cnt; i++)
		env->prog->aux->func_info[i].insn_offset = env->subprog_info[i].start;
		env->prog->aux->func_info[i].insn_off = env->subprog_info[i].start;
}

/* check %cur's range satisfies %old's */
+7 −0
Original line number Diff line number Diff line
@@ -589,6 +589,13 @@ static int do_dump(int argc, char **argv)
		goto err_free;
	}

	if (func_info && !info.func_info) {
		/* kernel.kptr_restrict is set.  No func_info available. */
		free(func_info);
		func_info = NULL;
		finfo_cnt = 0;
	}

	if ((member_len == &info.jited_prog_len &&
	     info.jited_prog_insns == 0) ||
	    (member_len == &info.xlated_prog_len &&
Loading