Skip to content

Commit 7337224

Browse files
iamkafaiAlexei Starovoitov
authored andcommitted
bpf: Improve the info.func_info and info.func_info_rec_size behavior
1) When bpf_dump_raw_ok() == false and the kernel can provide >=1 func_info to the userspace, the current behavior is setting the info.func_info_cnt to 0 instead of setting info.func_info to 0. It is different from the behavior in jited_func_lens/nr_jited_func_lens, jited_ksyms/nr_jited_ksyms...etc. This patch fixes it. (i.e. set func_info to 0 instead of func_info_cnt to 0 when bpf_dump_raw_ok() == false). 2) When the userspace passed in info.func_info_cnt == 0, the kernel will set the expected func_info size back to the info.func_info_rec_size. It is a way for the userspace to learn the kernel expected func_info_rec_size introduced in commit 838e969 ("bpf: Introduce bpf_func_info"). An exception is the kernel expected size is not set when func_info is not available for a bpf_prog. This makes the returned info.func_info_rec_size has different values depending on the returned value of info.func_info_cnt. This patch sets the kernel expected size to info.func_info_rec_size independent of the info.func_info_cnt. 3) The current logic only rejects invalid func_info_rec_size if func_info_cnt is non zero. This patch also rejects invalid nonzero info.func_info_rec_size and not equal to the kernel expected size. 4) Set info.btf_id as long as prog->aux->btf != NULL. That will setup the later copy_to_user() codes look the same as others which then easier to understand and maintain. prog->aux->btf is not NULL only if prog->aux->func_info_cnt > 0. Breaking up info.btf_id from prog->aux->func_info_cnt is needed for the later line info patch anyway. A similar change is made to bpf_get_prog_name(). Fixes: 838e969 ("bpf: Introduce bpf_func_info") Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 30da46b commit 7337224

File tree

2 files changed

+21
-27
lines changed

2 files changed

+21
-27
lines changed

kernel/bpf/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ static void bpf_get_prog_name(const struct bpf_prog *prog, char *sym)
410410
sym = bin2hex(sym, prog->tag, sizeof(prog->tag));
411411

412412
/* prog->aux->name will be ignored if full btf name is available */
413-
if (prog->aux->btf) {
413+
if (prog->aux->func_info_cnt) {
414414
type = btf_type_by_id(prog->aux->btf,
415415
prog->aux->func_info[prog->aux->func_idx].type_id);
416416
func_name = btf_name_by_offset(prog->aux->btf, type->name_off);

kernel/bpf/syscall.c

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
20832083
return -EFAULT;
20842084
}
20852085

2086+
if ((info.func_info_cnt || info.func_info_rec_size) &&
2087+
info.func_info_rec_size != sizeof(struct bpf_func_info))
2088+
return -EINVAL;
2089+
2090+
info.func_info_rec_size = sizeof(struct bpf_func_info);
2091+
20862092
if (!capable(CAP_SYS_ADMIN)) {
20872093
info.jited_prog_len = 0;
20882094
info.xlated_prog_len = 0;
@@ -2226,35 +2232,23 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
22262232
}
22272233
}
22282234

2229-
if (prog->aux->btf) {
2230-
u32 krec_size = sizeof(struct bpf_func_info);
2231-
u32 ucnt, urec_size;
2232-
2235+
if (prog->aux->btf)
22332236
info.btf_id = btf_id(prog->aux->btf);
22342237

2235-
ucnt = info.func_info_cnt;
2236-
info.func_info_cnt = prog->aux->func_info_cnt;
2237-
urec_size = info.func_info_rec_size;
2238-
info.func_info_rec_size = krec_size;
2239-
if (ucnt) {
2240-
/* expect passed-in urec_size is what the kernel expects */
2241-
if (urec_size != info.func_info_rec_size)
2242-
return -EINVAL;
2243-
2244-
if (bpf_dump_raw_ok()) {
2245-
char __user *user_finfo;
2246-
2247-
user_finfo = u64_to_user_ptr(info.func_info);
2248-
ucnt = min_t(u32, info.func_info_cnt, ucnt);
2249-
if (copy_to_user(user_finfo, prog->aux->func_info,
2250-
krec_size * ucnt))
2251-
return -EFAULT;
2252-
} else {
2253-
info.func_info_cnt = 0;
2254-
}
2238+
ulen = info.func_info_cnt;
2239+
info.func_info_cnt = prog->aux->func_info_cnt;
2240+
if (info.func_info_cnt && ulen) {
2241+
if (bpf_dump_raw_ok()) {
2242+
char __user *user_finfo;
2243+
2244+
user_finfo = u64_to_user_ptr(info.func_info);
2245+
ulen = min_t(u32, info.func_info_cnt, ulen);
2246+
if (copy_to_user(user_finfo, prog->aux->func_info,
2247+
info.func_info_rec_size * ulen))
2248+
return -EFAULT;
2249+
} else {
2250+
info.func_info = 0;
22552251
}
2256-
} else {
2257-
info.func_info_cnt = 0;
22582252
}
22592253

22602254
done:

0 commit comments

Comments
 (0)