summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau2018-03-24 19:44:23 +0100
committerDaniel Borkmann2018-03-26 09:58:17 +0200
commit77d2e05abd45886dcad2b632c738cf46b9f7c19e (patch)
treedab2d5beef6275329e8ed3dbaff7f720d6f05f6c
parentbpf: Rename bpf_verifer_log (diff)
downloadkernel-qcow2-linux-77d2e05abd45886dcad2b632c738cf46b9f7c19e.tar.gz
kernel-qcow2-linux-77d2e05abd45886dcad2b632c738cf46b9f7c19e.tar.xz
kernel-qcow2-linux-77d2e05abd45886dcad2b632c738cf46b9f7c19e.zip
bpf: Add bpf_verifier_vlog() and bpf_verifier_log_needed()
The BTF (BPF Type Format) verifier needs to reuse the current BPF verifier log. Hence, it requires the following changes: (1) Expose log_write() in verifier.c for other users. Its name is renamed to bpf_verifier_vlog(). (2) The BTF verifier also needs to check 'log->level && log->ubuf && !bpf_verifier_log_full(log);' independently outside of the current log_write(). It is because the BTF verifier will do one-check before making multiple calls to btf_verifier_vlog to log the details of a type. Hence, this check is also re-factored to a new function bpf_verifier_log_needed(). Since it is re-factored, we can check it before va_start() in the current bpf_verifier_log_write() and verbose(). Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Alexei Starovoitov <ast@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--include/linux/bpf_verifier.h7
-rw-r--r--kernel/bpf/verifier.c19
2 files changed, 18 insertions, 8 deletions
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index c30668414b22..7e61c395fddf 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -166,6 +166,11 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifier_log *log)
return log->len_used >= log->len_total - 1;
}
+static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
+{
+ return log->level && log->ubuf && !bpf_verifier_log_full(log);
+}
+
#define BPF_MAX_SUBPROGS 256
/* single container for all structs
@@ -192,6 +197,8 @@ struct bpf_verifier_env {
u32 subprog_cnt;
};
+void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
+ va_list args);
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
const char *fmt, ...);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1e84e02ff733..8acd2207e412 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -168,15 +168,11 @@ struct bpf_call_arg_meta {
static DEFINE_MUTEX(bpf_verifier_lock);
-static void log_write(struct bpf_verifier_env *env, const char *fmt,
- va_list args)
+void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
+ va_list args)
{
- struct bpf_verifier_log *log = &env->log;
unsigned int n;
- if (!log->level || !log->ubuf || bpf_verifier_log_full(log))
- return;
-
n = vscnprintf(log->kbuf, BPF_VERIFIER_TMP_LOG_SIZE, fmt, args);
WARN_ONCE(n >= BPF_VERIFIER_TMP_LOG_SIZE - 1,
@@ -200,18 +196,25 @@ __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
{
va_list args;
+ if (!bpf_verifier_log_needed(&env->log))
+ return;
+
va_start(args, fmt);
- log_write(env, fmt, args);
+ bpf_verifier_vlog(&env->log, fmt, args);
va_end(args);
}
EXPORT_SYMBOL_GPL(bpf_verifier_log_write);
__printf(2, 3) static void verbose(void *private_data, const char *fmt, ...)
{
+ struct bpf_verifier_env *env = private_data;
va_list args;
+ if (!bpf_verifier_log_needed(&env->log))
+ return;
+
va_start(args, fmt);
- log_write(private_data, fmt, args);
+ bpf_verifier_vlog(&env->log, fmt, args);
va_end(args);
}