All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
To: Kumar Kartikeya Dwivedi <memxor@gmail.com>, bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Ihor Solodrai <ihor.solodrai@linux.dev>,
	kkd@meta.com, kernel-team@meta.com
Subject: Re: [PATCH bpf-next v1 2/3] bpf: Emit verifier warnings through prog stderr
Date: Mon, 30 Mar 2026 12:39:09 +0100	[thread overview]
Message-ID: <87o6k5h7he.fsf@gmail.com> (raw)
In-Reply-To: <20260329212534.3270005-3-memxor@gmail.com>

Kumar Kartikeya Dwivedi <memxor@gmail.com> writes:

> There is a class of messages that aren't treated as hard errors, such
> that the program must be rejected, but should be surfaced to the user to
> make them aware that while the program succeeded, parts of their program
> are exhibiting behavior that needs attention. One example is usage of
> kfuncs that are supposed to be deprecated, and may be dropped in the
> future, though are preserved for now for backwards compatibility.
>
> Add support for emitting a warning message to the BPF program's stderr
> stream whenever we detect usage of a _impl suffixed kfunc, which have
> now been replaced with KF_IMPLICIT_ARGS variants. For this purpose,
> introduce bpf_stream_pr_warn() as a convenience wrapper, and then mark
> bpf_find_linfo() as global to allow its usage in the verifier to find
> the linfo corresponding to an instruction index.
>
> To make the message more helpful, recommend usage of bpf_ksym_exists()
> as a way for the user to write backwards compatible BPF code that works
> on older kernels offering _impl suffixed kfuncs.
>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> ---
In the commit message: ..such that the program must __not__ be rejected..
>  include/linux/bpf.h          |  9 ++++++
>  include/linux/bpf_verifier.h |  3 +-
>  kernel/bpf/log.c             |  6 ++--
>  kernel/bpf/verifier.c        | 53 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 67 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 2c4f92085d79..d0158edd27b2 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -3912,6 +3912,15 @@ int bpf_stream_stage_dump_stack(struct bpf_stream_stage *ss);
>  		bpf_stream_stage_free(&ss);                    \
>  	})
>  
> +#define bpf_stream_pr_warn(prog, fmt, ...)                              \
> +	({                                                              \
> +		struct bpf_stream_stage __ss;                           \
> +									\
> +		bpf_stream_stage(__ss, prog, BPF_STDERR, ({		\
> +			bpf_stream_printk(__ss, fmt, ##__VA_ARGS__);	\
> +		}));							\
> +	})
> +
>  #ifdef CONFIG_BPF_LSM
>  void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype);
>  void bpf_cgroup_atype_put(int cgroup_atype);
> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> index 090aa26d1c98..5683c06f5a90 100644
> --- a/include/linux/bpf_verifier.h
> +++ b/include/linux/bpf_verifier.h
> @@ -873,7 +873,8 @@ int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
>  		  char __user *log_buf, u32 log_size);
>  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);
> -
> +const struct bpf_line_info *bpf_find_linfo(const struct bpf_verifier_env *env,
> +					   u32 insn_off);
>  __printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
>  				  u32 insn_off,
>  				  const char *prefix_fmt, ...);
> diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
> index 37d72b052192..598b494ded36 100644
> --- a/kernel/bpf/log.c
> +++ b/kernel/bpf/log.c
> @@ -329,8 +329,8 @@ __printf(2, 3) void bpf_log(struct bpf_verifier_log *log,
>  }
>  EXPORT_SYMBOL_GPL(bpf_log);
>  
> -static const struct bpf_line_info *
> -find_linfo(const struct bpf_verifier_env *env, u32 insn_off)
> +const struct bpf_line_info *
> +bpf_find_linfo(const struct bpf_verifier_env *env, u32 insn_off)
>  {
>  	const struct bpf_line_info *linfo;
>  	const struct bpf_prog *prog;
> @@ -390,7 +390,7 @@ __printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
>  		return;
>  
>  	prev_linfo = env->prev_linfo;
> -	linfo = find_linfo(env, insn_off);
> +	linfo = bpf_find_linfo(env, insn_off);
>  	if (!linfo || linfo == prev_linfo)
>  		return;
>  
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 8c1cf2eb6cbb..f50e0ebd0ded 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -3206,6 +3206,7 @@ struct bpf_kfunc_desc {
>  	u32 func_id;
>  	s32 imm;
>  	u16 offset;
> +	bool warned_deprecated;
>  	unsigned long addr;
>  };
>  
> @@ -14045,6 +14046,53 @@ static int fetch_kfunc_arg_meta(struct bpf_verifier_env *env,
>  	return 0;
>  }
>  
> +static bool get_insn_file_line(const struct bpf_verifier_env *env, u32 insn_off,
> +			       const char **filep, int *linep)
> +{
> +	const struct bpf_line_info *linfo;
> +
> +	if (!env->prog->aux->btf)
> +		return false;
> +
> +	linfo = bpf_find_linfo(env, insn_off);
> +	if (!linfo)
> +		return false;
> +
> +	if (bpf_get_linfo_file_line(env->prog->aux->btf, linfo, filep, NULL, linep))
> +		return false;
> +	return true;
> +}
> +
> +static void warn_for_deprecated_kfuncs(struct bpf_verifier_env *env,
> +				       struct bpf_kfunc_desc *desc,
> +				       const char *func_name,
> +				       int insn_idx)
> +{
> +	int repl_len, line;
> +	const char *file;
> +
> +	if (desc->warned_deprecated)
> +		return;
> +
> +	if (!func_name || !strends(func_name, KF_IMPL_SUFFIX))
> +		return;
> +
> +	repl_len = strlen(func_name) - strlen(KF_IMPL_SUFFIX);
> +
> +	if (get_insn_file_line(env, insn_idx, &file, &line))
> +		snprintf(env->tmp_str_buf, TMP_STR_BUF_LEN, "%s:%u", file, line);
> +	else
> +		snprintf(env->tmp_str_buf, TMP_STR_BUF_LEN, "insn #%d", insn_idx);
> +
> +	bpf_stream_pr_warn(env->prog,
> +			   "WARNING: %s calls deprecated kfunc %s(), which will be removed.\n"
> +			   "WARNING: Switch to kfunc %.*s() instead.\n"
> +			   "WARNING: For older kernels, choose the kfunc using bpf_ksym_exists(%.*s).\n",
> +			   env->tmp_str_buf, func_name, repl_len, func_name, repl_len, func_name);
> +
> +	desc->warned_deprecated = true;
> +}
Commit message suggests this is a generic functionality that we plan to
use for all kinds of deprecations, but this function looks tightly
coupled to KF_IMPL_SUFFIX functions. I think we can make it a bit
friendlier to extending if split into 2 separate helpers:
is_kfunc_deprecated() and warn_deprecated_kfunc(), so in future new
logic for detecting deprecated funcs goes straight to
is_kfunc_deprecated() and we make sure printing and file/line
extractions are not changed. 
> +
>  /* check special kfuncs and return:
>   *  1  - not fall-through to 'else' branch, continue verification
>   *  0  - fall-through to 'else' branch
> @@ -14231,6 +14279,7 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
>  {
>  	bool sleepable, rcu_lock, rcu_unlock, preempt_disable, preempt_enable;
>  	u32 i, nargs, ptr_type_id, release_ref_obj_id;
> +	struct bpf_kfunc_desc *desc;
>  	struct bpf_reg_state *regs = cur_regs(env);
>  	const char *func_name, *ptr_type_name;
>  	const struct btf_type *t, *ptr_type;
> @@ -14253,6 +14302,10 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
>  	func_name = meta.func_name;
>  	insn_aux = &env->insn_aux_data[insn_idx];
>  
> +	desc = find_kfunc_desc(env->prog, insn->imm, insn->off);
> +	if (desc)
> +		warn_for_deprecated_kfuncs(env, desc, func_name, insn_idx);
> +
>  	insn_aux->is_iter_next = is_iter_next_kfunc(&meta);
>  
>  	if (!insn->off &&
> -- 
> 2.52.0

  reply	other threads:[~2026-03-30 11:39 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-29 21:25 [PATCH bpf-next v1 0/3] Add support to emit verifier warnings Kumar Kartikeya Dwivedi
2026-03-29 21:25 ` [PATCH bpf-next v1 1/3] bpf: Extract bpf_get_linfo_file_line Kumar Kartikeya Dwivedi
2026-03-30 11:28   ` Mykyta Yatsenko
2026-03-30 12:27   ` Puranjay Mohan
2026-03-30 12:35   ` Puranjay Mohan
2026-03-29 21:25 ` [PATCH bpf-next v1 2/3] bpf: Emit verifier warnings through prog stderr Kumar Kartikeya Dwivedi
2026-03-30 11:39   ` Mykyta Yatsenko [this message]
2026-03-30 12:39     ` Puranjay Mohan
2026-03-30 15:02   ` Alexei Starovoitov
2026-03-29 21:25 ` [PATCH bpf-next v1 3/3] libbpf: Wire up verifier warning display logic Kumar Kartikeya Dwivedi
2026-03-30 12:56   ` Mykyta Yatsenko
2026-03-30 23:46   ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o6k5h7he.fsf@gmail.com \
    --to=mykyta.yatsenko5@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=kernel-team@meta.com \
    --cc=kkd@meta.com \
    --cc=martin.lau@kernel.org \
    --cc=memxor@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.