lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210920151112.3770991-2-davemarchevsky@fb.com>
Date:   Mon, 20 Sep 2021 08:11:11 -0700
From:   Dave Marchevsky <davemarchevsky@...com>
To:     <bpf@...r.kernel.org>
CC:     <netdev@...r.kernel.org>, Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        Andrii Nakryiko <andrii@...nel.org>,
        Yonghong Song <yhs@...com>,
        Dave Marchevsky <davemarchevsky@...com>
Subject: [RFC PATCH bpf-next 1/2] bpf: add verifier stats to bpf_prog_info and fdinfo

These stats are currently printed in the verifier log and not stored
anywhere. To ease consumption of this data, add a bpf_prog_verif_stats
struct to bpf_prog_aux so they can be exposed via BPF_OBJ_GET_INFO_BY_FD
and fdinfo.

Signed-off-by: Dave Marchevsky <davemarchevsky@...com>
---
 include/linux/bpf.h            |  1 +
 include/uapi/linux/bpf.h       | 10 ++++++++++
 kernel/bpf/syscall.c           | 20 ++++++++++++++++++--
 kernel/bpf/verifier.c          | 13 +++++++++++++
 tools/include/uapi/linux/bpf.h | 10 ++++++++++
 5 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b6c45a6cbbba..206c19b253b7 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -876,6 +876,7 @@ struct bpf_prog_aux {
 	struct bpf_kfunc_desc_tab *kfunc_tab;
 	u32 size_poke_tab;
 	struct bpf_ksym ksym;
+	struct bpf_prog_verif_stats verif_stats;
 	const struct bpf_prog_ops *ops;
 	struct bpf_map **used_maps;
 	struct mutex used_maps_mutex; /* mutex for used_maps and used_map_cnt */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 6fc59d61937a..cb0fa49e62d7 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5576,6 +5576,15 @@ struct sk_reuseport_md {
 
 #define BPF_TAG_SIZE	8
 
+struct bpf_prog_verif_stats {
+	__u64 verification_time;
+	__u32 insn_processed;
+	__u32 max_states_per_insn;
+	__u32 total_states;
+	__u32 peak_states;
+	__u32 longest_mark_read_walk;
+};
+
 struct bpf_prog_info {
 	__u32 type;
 	__u32 id;
@@ -5613,6 +5622,7 @@ struct bpf_prog_info {
 	__u64 run_time_ns;
 	__u64 run_cnt;
 	__u64 recursion_misses;
+	struct bpf_prog_verif_stats verif_stats;
 } __attribute__((aligned(8)));
 
 struct bpf_map_info {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4e50c0bfdb7d..0fa95ebd4276 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1836,9 +1836,11 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
 {
 	const struct bpf_prog *prog = filp->private_data;
 	char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
+	struct bpf_prog_verif_stats *verif_stats;
 	struct bpf_prog_stats stats;
 
 	bpf_prog_get_stats(prog, &stats);
+	verif_stats = &prog->aux->verif_stats;
 	bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
 	seq_printf(m,
 		   "prog_type:\t%u\n"
@@ -1848,7 +1850,13 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
 		   "prog_id:\t%u\n"
 		   "run_time_ns:\t%llu\n"
 		   "run_cnt:\t%llu\n"
-		   "recursion_misses:\t%llu\n",
+		   "recursion_misses:\t%llu\n"
+		   "verification_time:\t%llu\n"
+		   "verif_insn_processed:\t%u\n"
+		   "verif_max_states_per_insn:\t%u\n"
+		   "verif_total_states:\t%u\n"
+		   "verif_peak_states:\t%u\n"
+		   "verif_longest_mark_read_walk:\t%u\n",
 		   prog->type,
 		   prog->jited,
 		   prog_tag,
@@ -1856,7 +1864,13 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
 		   prog->aux->id,
 		   stats.nsecs,
 		   stats.cnt,
-		   stats.misses);
+		   stats.misses,
+		   verif_stats->verification_time,
+		   verif_stats->insn_processed,
+		   verif_stats->max_states_per_insn,
+		   verif_stats->total_states,
+		   verif_stats->peak_states,
+		   verif_stats->longest_mark_read_walk);
 }
 #endif
 
@@ -3625,6 +3639,8 @@ static int bpf_prog_get_info_by_fd(struct file *file,
 	info.run_cnt = stats.cnt;
 	info.recursion_misses = stats.misses;
 
+	info.verif_stats = prog->aux->verif_stats;
+
 	if (!bpf_capable()) {
 		info.jited_prog_len = 0;
 		info.xlated_prog_len = 0;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e76b55917905..97cd3b71d5ae 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13245,6 +13245,18 @@ static void print_verification_stats(struct bpf_verifier_env *env)
 		env->peak_states, env->longest_mark_read_walk);
 }
 
+static void populate_aux_verif_stats(struct bpf_verifier_env *env)
+{
+	struct bpf_prog_verif_stats *verif_stats = &env->prog->aux->verif_stats;
+
+	verif_stats->verification_time = env->verification_time;
+	verif_stats->insn_processed = env->insn_processed;
+	verif_stats->max_states_per_insn = env->max_states_per_insn;
+	verif_stats->total_states = env->total_states;
+	verif_stats->peak_states = env->peak_states;
+	verif_stats->longest_mark_read_walk = env->longest_mark_read_walk;
+}
+
 static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
 {
 	const struct btf_type *t, *func_proto;
@@ -13826,6 +13838,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr)
 
 	env->verification_time = ktime_get_ns() - start_time;
 	print_verification_stats(env);
+	populate_aux_verif_stats(env);
 
 	if (log->level && bpf_verifier_log_full(log))
 		ret = -ENOSPC;
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 6fc59d61937a..cb0fa49e62d7 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5576,6 +5576,15 @@ struct sk_reuseport_md {
 
 #define BPF_TAG_SIZE	8
 
+struct bpf_prog_verif_stats {
+	__u64 verification_time;
+	__u32 insn_processed;
+	__u32 max_states_per_insn;
+	__u32 total_states;
+	__u32 peak_states;
+	__u32 longest_mark_read_walk;
+};
+
 struct bpf_prog_info {
 	__u32 type;
 	__u32 id;
@@ -5613,6 +5622,7 @@ struct bpf_prog_info {
 	__u64 run_time_ns;
 	__u64 run_cnt;
 	__u64 recursion_misses;
+	struct bpf_prog_verif_stats verif_stats;
 } __attribute__((aligned(8)));
 
 struct bpf_map_info {
-- 
2.30.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ