Skip to content

Commit a06aef4

Browse files
author
Alexei Starovoitov
committed
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: Alexei Starovoitov <ast@kernel.org>
2 parents 30da46b + 84ecc1f commit a06aef4

File tree

9 files changed

+54
-47
lines changed

9 files changed

+54
-47
lines changed

include/uapi/linux/bpf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2991,7 +2991,7 @@ struct bpf_flow_keys {
29912991
};
29922992

29932993
struct bpf_func_info {
2994-
__u32 insn_offset;
2994+
__u32 insn_off;
29952995
__u32 type_id;
29962996
};
29972997

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:

kernel/bpf/verifier.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4707,24 +4707,24 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
47074707
goto free_btf;
47084708
}
47094709

4710-
/* check insn_offset */
4710+
/* check insn_off */
47114711
if (i == 0) {
4712-
if (krecord[i].insn_offset) {
4712+
if (krecord[i].insn_off) {
47134713
verbose(env,
4714-
"nonzero insn_offset %u for the first func info record",
4715-
krecord[i].insn_offset);
4714+
"nonzero insn_off %u for the first func info record",
4715+
krecord[i].insn_off);
47164716
ret = -EINVAL;
47174717
goto free_btf;
47184718
}
4719-
} else if (krecord[i].insn_offset <= prev_offset) {
4719+
} else if (krecord[i].insn_off <= prev_offset) {
47204720
verbose(env,
47214721
"same or smaller insn offset (%u) than previous func info record (%u)",
4722-
krecord[i].insn_offset, prev_offset);
4722+
krecord[i].insn_off, prev_offset);
47234723
ret = -EINVAL;
47244724
goto free_btf;
47254725
}
47264726

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

4742-
prev_offset = krecord[i].insn_offset;
4742+
prev_offset = krecord[i].insn_off;
47434743
urecord += urec_size;
47444744
}
47454745

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

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

47684768
/* check %cur's range satisfies %old's */

tools/bpf/bpftool/prog.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,13 @@ static int do_dump(int argc, char **argv)
589589
goto err_free;
590590
}
591591

592+
if (func_info && !info.func_info) {
593+
/* kernel.kptr_restrict is set. No func_info available. */
594+
free(func_info);
595+
func_info = NULL;
596+
finfo_cnt = 0;
597+
}
598+
592599
if ((member_len == &info.jited_prog_len &&
593600
info.jited_prog_insns == 0) ||
594601
(member_len == &info.xlated_prog_len &&

tools/bpf/bpftool/xlated_dumper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
261261
jsonw_start_object(json_wtr);
262262

263263
if (btf && record) {
264-
if (record->insn_offset == i) {
264+
if (record->insn_off == i) {
265265
btf_dumper_type_only(btf, record->type_id,
266266
func_sig,
267267
sizeof(func_sig));
@@ -330,7 +330,7 @@ void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
330330
}
331331

332332
if (btf && record) {
333-
if (record->insn_offset == i) {
333+
if (record->insn_off == i) {
334334
btf_dumper_type_only(btf, record->type_id,
335335
func_sig,
336336
sizeof(func_sig));

tools/include/uapi/linux/bpf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2991,7 +2991,7 @@ struct bpf_flow_keys {
29912991
};
29922992

29932993
struct bpf_func_info {
2994-
__u32 insn_offset;
2994+
__u32 insn_off;
29952995
__u32 type_id;
29962996
};
29972997

tools/lib/bpf/btf.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct btf_ext {
4545

4646
/* The minimum bpf_func_info checked by the loader */
4747
struct bpf_func_info_min {
48-
__u32 insn_offset;
48+
__u32 insn_off;
4949
__u32 type_id;
5050
};
5151

@@ -670,7 +670,7 @@ int btf_ext__reloc_init(struct btf *btf, struct btf_ext *btf_ext,
670670

671671
memcpy(data, sinfo->data, records_len);
672672

673-
/* adjust the insn_offset, the data in .BTF.ext is
673+
/* adjust the insn_off, the data in .BTF.ext is
674674
* the actual byte offset, and the kernel expects
675675
* the offset in term of bpf_insn.
676676
*
@@ -681,7 +681,7 @@ int btf_ext__reloc_init(struct btf *btf, struct btf_ext *btf_ext,
681681
struct bpf_func_info_min *record;
682682

683683
record = data + i * record_size;
684-
record->insn_offset /= sizeof(struct bpf_insn);
684+
record->insn_off /= sizeof(struct bpf_insn);
685685
}
686686

687687
*func_info = data;
@@ -722,15 +722,15 @@ int btf_ext__reloc(struct btf *btf, struct btf_ext *btf_ext,
722722
return -ENOMEM;
723723

724724
memcpy(data + existing_flen, sinfo->data, records_len);
725-
/* adjust insn_offset only, the rest data will be passed
725+
/* adjust insn_off only, the rest data will be passed
726726
* to the kernel.
727727
*/
728728
for (i = 0; i < sinfo->num_func_info; i++) {
729729
struct bpf_func_info_min *record;
730730

731731
record = data + existing_flen + i * record_size;
732-
record->insn_offset =
733-
record->insn_offset / sizeof(struct bpf_insn) +
732+
record->insn_off =
733+
record->insn_off / sizeof(struct bpf_insn) +
734734
insns_cnt;
735735
}
736736
*func_info = data;

tools/testing/selftests/bpf/test_btf.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3156,7 +3156,7 @@ static struct btf_func_type_test {
31563156
},
31573157

31583158
{
3159-
.descr = "func_type (Incorrect bpf_func_info.insn_offset)",
3159+
.descr = "func_type (Incorrect bpf_func_info.insn_off)",
31603160
.raw_types = {
31613161
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
31623162
BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
@@ -3303,6 +3303,12 @@ static int do_test_func_type(int test_num)
33033303
goto done;
33043304
}
33053305

3306+
if (CHECK(!info.func_info,
3307+
"info.func_info == 0. kernel.kptr_restrict is set?")) {
3308+
err = -1;
3309+
goto done;
3310+
}
3311+
33063312
finfo = func_info;
33073313
for (i = 0; i < 2; i++) {
33083314
if (CHECK(finfo->type_id != test->func_info[i][1],

0 commit comments

Comments
 (0)