[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112145616.44195-4-leon.hwang@linux.dev>
Date: Mon, 12 Jan 2026 22:56:10 +0800
From: Leon Hwang <leon.hwang@...ux.dev>
To: bpf@...r.kernel.org
Cc: Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
John Fastabend <john.fastabend@...il.com>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <martin.lau@...ux.dev>,
Eduard Zingerman <eddyz87@...il.com>,
Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>,
KP Singh <kpsingh@...nel.org>,
Stanislav Fomichev <sdf@...ichev.me>,
Hao Luo <haoluo@...gle.com>,
Jiri Olsa <jolsa@...nel.org>,
Shuah Khan <shuah@...nel.org>,
Christian Brauner <brauner@...nel.org>,
Seth Forshee <sforshee@...nel.org>,
Yuichiro Tsuji <yuichtsu@...zon.com>,
Andrey Albershteyn <aalbersh@...hat.com>,
Leon Hwang <leon.hwang@...ux.dev>,
Willem de Bruijn <willemb@...gle.com>,
Jason Xing <kerneljasonxing@...il.com>,
Tao Chen <chen.dylane@...ux.dev>,
Mykyta Yatsenko <yatsenko@...a.com>,
Kumar Kartikeya Dwivedi <memxor@...il.com>,
Anton Protopopov <a.s.protopopov@...il.com>,
Amery Hung <ameryhung@...il.com>,
Rong Tao <rongtao@...tc.cn>,
linux-kernel@...r.kernel.org,
linux-api@...r.kernel.org,
linux-kselftest@...r.kernel.org,
kernel-patches-bot@...com
Subject: [PATCH bpf-next v5 3/9] bpf: Refactor reporting log_true_size for prog_load
The next commit will add support for reporting logs via extended common
attributes, including 'log_true_size'.
To prepare for that, refactor the 'log_true_size' reporting logic by
introducing a new struct bpf_log_attr to encapsulate log-related behavior:
* bpf_prog_load_log_attr_init(): initialize the log fields, which will
support extended common attributes in the next commit.
* bpf_log_attr_finalize(): handle log finalization and write back
'log_true_size' to userspace.
Signed-off-by: Leon Hwang <leon.hwang@...ux.dev>
---
include/linux/bpf.h | 19 ++++++++++++++++-
include/linux/bpf_verifier.h | 11 ++++++++++
kernel/bpf/log.c | 40 ++++++++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 9 +++++++-
kernel/bpf/verifier.c | 19 ++++++-----------
5 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 5936f8e2996f..3a525a7e8747 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2867,8 +2867,25 @@ int bpf_get_file_flag(int flags);
int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size,
size_t actual_size);
+struct bpf_attrs {
+ const void *attr;
+ bpfptr_t uattr;
+ u32 size;
+};
+
+static inline void bpf_attrs_init(struct bpf_attrs *attrs, const void *attr, bpfptr_t uattr,
+ u32 size)
+{
+ memset(attrs, 0, sizeof(*attrs));
+ attrs->attr = attr;
+ attrs->uattr = uattr;
+ attrs->size = size;
+}
+
/* verify correctness of eBPF program */
-int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size);
+struct bpf_log_attr;
+int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_log_attr *log_attr);
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 130bcbd66f60..4c9632c40059 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -631,6 +631,17 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
return log && log->level;
}
+struct bpf_log_attr {
+ u64 log_buf;
+ u32 log_size;
+ u32 log_level;
+ struct bpf_attrs *attrs;
+ u32 offsetof_log_true_size;
+};
+
+int bpf_prog_load_log_attr_init(struct bpf_log_attr *log_attr, struct bpf_attrs *attrs);
+int bpf_log_attr_finalize(struct bpf_log_attr *log_attr, struct bpf_verifier_log *log);
+
#define BPF_MAX_SUBPROGS 256
struct bpf_subprog_arg_info {
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index a0c3b35de2ce..457b724c4176 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -863,3 +863,43 @@ void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_st
}
print_verifier_state(env, vstate, frameno, false);
}
+
+static int bpf_log_attr_init(struct bpf_log_attr *log_attr, struct bpf_attrs *attrs, u64 log_buf,
+ u32 log_size, u32 log_level, int offsetof_log_true_size)
+{
+ memset(log_attr, 0, sizeof(*log_attr));
+ log_attr->log_buf = log_buf;
+ log_attr->log_size = log_size;
+ log_attr->log_level = log_level;
+ log_attr->attrs = attrs;
+ log_attr->offsetof_log_true_size = offsetof_log_true_size;
+ return 0;
+}
+
+int bpf_prog_load_log_attr_init(struct bpf_log_attr *log_attr, struct bpf_attrs *attrs)
+{
+ const union bpf_attr *attr = attrs->attr;
+
+ return bpf_log_attr_init(log_attr, attrs, attr->log_buf, attr->log_size, attr->log_level,
+ offsetof(union bpf_attr, log_true_size));
+}
+
+int bpf_log_attr_finalize(struct bpf_log_attr *log_attr, struct bpf_verifier_log *log)
+{
+ u32 log_true_size, off;
+ size_t size;
+ int err;
+
+ if (!log)
+ return 0;
+
+ err = bpf_vlog_finalize(log, &log_true_size);
+
+ size = sizeof(log_true_size);
+ off = log_attr->offsetof_log_true_size;
+ if (log_attr->attrs && log_attr->attrs->size >= off + size &&
+ copy_to_bpfptr_offset(log_attr->attrs->uattr, off, &log_true_size, size))
+ err = -EFAULT;
+
+ return err;
+}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index af703f7ea58e..0b389bc6add8 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2871,6 +2871,8 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
struct bpf_prog *prog, *dst_prog = NULL;
struct btf *attach_btf = NULL;
struct bpf_token *token = NULL;
+ struct bpf_log_attr log_attr;
+ struct bpf_attrs attrs;
bool bpf_cap;
int err;
char license[128];
@@ -3082,8 +3084,13 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
if (err)
goto free_prog_sec;
+ bpf_attrs_init(&attrs, attr, uattr, uattr_size);
+ err = bpf_prog_load_log_attr_init(&log_attr, &attrs);
+ if (err < 0)
+ goto free_used_maps;
+
/* run eBPF verifier */
- err = bpf_check(&prog, attr, uattr, uattr_size);
+ err = bpf_check(&prog, attr, uattr, &log_attr);
if (err < 0)
goto free_used_maps;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 53635ea2e41b..921a7b6a6686 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -25106,12 +25106,12 @@ static int compute_scc(struct bpf_verifier_env *env)
return err;
}
-int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_log_attr *log_attr)
{
u64 start_time = ktime_get_ns();
struct bpf_verifier_env *env;
int i, len, ret = -EINVAL, err;
- u32 log_true_size;
bool is_priv;
BTF_TYPE_EMIT(enum bpf_features);
@@ -25158,9 +25158,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- ret = bpf_vlog_init(&env->log, attr->log_level,
- (char __user *) (unsigned long) attr->log_buf,
- attr->log_size);
+ ret = bpf_vlog_init(&env->log, log_attr->log_level,
+ u64_to_user_ptr(log_attr->log_buf),
+ log_attr->log_size);
if (ret)
goto err_unlock;
@@ -25310,17 +25310,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
env->prog->aux->verified_insns = env->insn_processed;
/* preserve original error even if log finalization is successful */
- err = bpf_vlog_finalize(&env->log, &log_true_size);
+ err = bpf_log_attr_finalize(log_attr, &env->log);
if (err)
ret = err;
- if (uattr_size >= offsetofend(union bpf_attr, log_true_size) &&
- copy_to_bpfptr_offset(uattr, offsetof(union bpf_attr, log_true_size),
- &log_true_size, sizeof(log_true_size))) {
- ret = -EFAULT;
- goto err_release_maps;
- }
-
if (ret)
goto err_release_maps;
--
2.52.0
Powered by blists - more mailing lists