Re: [PATCH] bpf: allow BPF_LOG_KERNEL from kernel space
From: Andrii Nakryiko
Date: Tue Jun 23 2026 - 16:53:35 EST
On Tue, Jun 23, 2026 at 8:34 AM Siddharth Nayyar <sidnayyar@xxxxxxxxxx> wrote:
>
> When loading a BPF program or BTF from kernel space (e.g. using a
> light skeleton generated loader module), the kernel module may want
> to output verifier logs to dmesg by setting attr->log_level =
> BPF_LOG_KERNEL (16).
>
> Currently, any attempt to do this through the standard syscall path
> (kern_sys_bpf -> bpf_vlog_init) fails with -EINVAL because
> bpf_verifier_log_attr_valid() rejects any log_level bit outside
> BPF_LOG_MASK. This prevents in-kernel loaders from successfully
> using BPF_LOG_KERNEL, causing silent failures if the BPF object
> is rejected by the verifier.
>
> This patch modifies bpf_vlog_init() to accept a new 'is_kernel'
> boolean (propagated from uattr.is_kernel) and allows BPF_LOG_KERNEL
> to pass the validation check strictly when invoked from kernel space.
>
> Signed-off-by: Siddharth Nayyar <sidnayyar@xxxxxxxxxx>
> ---
> include/linux/bpf_verifier.h | 2 +-
> kernel/bpf/btf.c | 3 ++-
> kernel/bpf/log.c | 17 +++++++++++------
> kernel/bpf/verifier.c | 3 ++-
> 4 files changed, 16 insertions(+), 9 deletions(-)
>
This feels a bit dirty. We already have BPF_LOG_KERNEL which is passed
through log_level, so wouldn't it be better to just make sure that
BPF_LOG_KERNEL is not rejected when program is loaded from inside the
kernel, instead of passing along extra bool everywhere?
> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> index 39a851e690ec..eb9d2a556c0e 100644
> --- a/include/linux/bpf_verifier.h
> +++ b/include/linux/bpf_verifier.h
> @@ -1059,7 +1059,7 @@ __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
> __printf(2, 3) void bpf_log(struct bpf_verifier_log *log,
> const char *fmt, ...);
> int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
> - char __user *log_buf, u32 log_size);
> + char __user *log_buf, u32 log_size, bool is_kernel);
> void bpf_vlog_reset(struct bpf_verifier_log *log, u64 new_pos);
> int bpf_vlog_finalize(struct bpf_verifier_log *log, u32 *log_size_actual);
>
[...]