Re: [PATCH bpf-next v9 3/9] bpf: Refactor reporting log_true_size for prog_load
From: Andrii Nakryiko <hidden>
Date: 2026-02-04 19:49:00
Also in:
bpf, linux-kselftest, lkml
On Mon, Feb 2, 2026 at 6:42 AM Leon Hwang [off-list ref] wrote:
quoted hunk ↗ jump to hunk
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 <redacted> --- include/linux/bpf.h | 4 +++- include/linux/bpf_verifier.h | 10 ++++++++++ kernel/bpf/log.c | 35 +++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 8 +++++--- kernel/bpf/verifier.c | 13 +++---------- 5 files changed, 56 insertions(+), 14 deletions(-)diff --git a/include/linux/bpf.h b/include/linux/bpf.h index cd9b96434904..d4dbcc7ad156 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h@@ -2913,7 +2913,9 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size, size_t actual_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 *attr_log); #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 8355b585cd18..c805b85b6f7a 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h@@ -631,6 +631,16 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log) return log && log->level; } +struct bpf_log_attr { + u32 offsetof_true_size; + u32 uattr_size; + bpfptr_t uattr; +}; + +int bpf_prog_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *attr, + bpfptr_t uattr, u32 size); +int bpf_log_attr_finalize(struct bpf_log_attr *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..ff579fcba36f 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c@@ -863,3 +863,38 @@ void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_st } print_verifier_state(env, vstate, frameno, false); } + +static void bpf_log_attr_init(struct bpf_log_attr *attr_log, int offsetof_true_size, bpfptr_t uattr, + u32 uattr_size) +{ + memset(attr_log, 0, sizeof(*attr_log)); + attr_log->offsetof_true_size = offsetof_true_size; + attr_log->uattr_size = uattr_size; + attr_log->uattr = uattr; +} + +int bpf_prog_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *attr, + bpfptr_t uattr, u32 size) +{ + bpf_log_attr_init(attr_log, offsetof(union bpf_attr, log_true_size), uattr, size); + return 0; +} + +int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log) +{ + u32 log_true_size; + size_t size; + int err; + + if (!log) + return 0;
can this ever happen? why guard against this?
+ + err = bpf_vlog_finalize(log, &log_true_size); + + size = sizeof(log_true_size); + if (attr->uattr_size >= attr->offsetof_true_size + size && + copy_to_bpfptr_offset(attr->uattr, attr->offsetof_true_size, &log_true_size, size)) + err = -EFAULT;
minor nit: return -EFAULT;
+ + return err; +}
[...]