All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Jiri Olsa <olsajiri@gmail.com>, Tamir Duberstein <tamird@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	 Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Kumar Kartikeya Dwivedi	 <memxor@gmail.com>,
	Song Liu <song@kernel.org>,
	Yonghong Song	 <yonghong.song@linux.dev>,
	Shuah Khan <shuah@kernel.org>, Andrea Righi	 <arighi@nvidia.com>,
	Xu Kuohai <xukuohai@huawei.com>,
	Andrea Righi	 <andrea.righi@canonical.com>,
	Bing-Jhong Billy Jheng <billy@starlabs.sg>,
	 David Vernet <void@manifault.com>,
	bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-kselftest@vger.kernel.org,
	Andrew Werner <awerner32@gmail.com>,
	Zvi Effron	 <zeffron@riotgames.com>,
	Andrii Nakryiko <andriin@fb.com>,
	Emil Tsalapatis	 <emil@etsalapatis.com>
Subject: Re: [PATCH bpf v2 2/8] libbpf: ringbuf: Prevent NULL callback crash
Date: Fri, 19 Jun 2026 14:11:56 -0700	[thread overview]
Message-ID: <130931685c8b2064325fc65a856ecd810c8a6b5c.camel@gmail.com> (raw)
In-Reply-To: <ajVKM9tJskwg9OFa@krava>

On Fri, 2026-06-19 at 15:54 +0200, Jiri Olsa wrote:
> On Thu, Jun 18, 2026 at 08:26:40PM -0400, Tamir Duberstein wrote:
> > ring_buffer__new() and ring_buffer__add() allow a NULL sample
> > callback. When callback-based consumption reaches such a ring, it calls
> > through the NULL function pointer and crashes.
> > 
> > Check every ring before manager polling or consumption so a missing
> > callback returns -EINVAL before the manager waits or consumes another
> > ring. Check the selected ring before direct per-ring consumption. Perform
> > both checks before honoring a zero record bound so invalid callback use
> > always reports the error.
> > 
> > Fixes: bf99c936f947 ("libbpf: Add BPF ring buffer support")
> > Assisted-by: Codex:gpt-5.5
> > Signed-off-by: Tamir Duberstein <tamird@kernel.org>
> > ---
> >  tools/lib/bpf/libbpf.h                           | 11 ++-
> >  tools/lib/bpf/ringbuf.c                          | 43 +++++++++--
> >  tools/testing/selftests/bpf/prog_tests/ringbuf.c | 93 ++++++++++++++++++++++++
> >  3 files changed, 136 insertions(+), 11 deletions(-)
> > 
> > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> > index bba4e8464396..9ba6b9ad3498 100644
> > --- a/tools/lib/bpf/libbpf.h
> > +++ b/tools/lib/bpf/libbpf.h
> > @@ -1526,18 +1526,17 @@ LIBBPF_API int ring__map_fd(const struct ring *r);
> >   *
> >   * @param r A ringbuffer object.
> >   * @return The number of records consumed (or INT_MAX, whichever is less), or
> > - * a negative number if any of the callbacks return an error.
> > + * a negative error code on failure.
> >   */
> >  LIBBPF_API int ring__consume(struct ring *r);
> >  
> >  /**
> > - * @brief **ring__consume_n()** consumes up to a requested amount of items from
> > - * a ringbuffer without event polling.
> > + * @brief **ring__consume_n()** consumes up to a requested number of records
> > + * from a ringbuffer without event polling.
> >   *
> >   * @param r A ringbuffer object.
> > - * @param n Maximum amount of items to consume.
> > - * @return The number of items consumed, or a negative number if any of the
> > - * callbacks return an error.
> > + * @param n Maximum number of records to consume.
> > + * @return The number of records consumed, or a negative error code on failure.
> >   */
> >  LIBBPF_API int ring__consume_n(struct ring *r, size_t n);
> >  
> > diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
> > index f2bb619d5a75..0dae4d95d309 100644
> > --- a/tools/lib/bpf/ringbuf.c
> > +++ b/tools/lib/bpf/ringbuf.c
> > @@ -231,6 +231,26 @@ static inline int roundup_len(__u32 len)
> >  	return (len + 7) / 8 * 8;
> >  }
> >  
> > +static int ringbuf_validate(const struct ring *r)
> > +{
> > +	if (unlikely(!r->sample_cb))
> > +		return -EINVAL;
> > +	return 0;
> > +}
> > +
> > +static int ringbuf_validate_callbacks(const struct ring_buffer *rb)
> > +{
> > +	int i, err;
> > +
> > +	for (i = 0; i < rb->ring_cnt; i++) {
> > +		err = ringbuf_validate(rb->rings[i]);
> > +		if (err)
> > +			return err;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int64_t ringbuf_process_ring(struct ring *r, size_t n)
> >  {
> >  	int *len_ptr, len, err;
> > @@ -240,6 +260,9 @@ static int64_t ringbuf_process_ring(struct ring *r, size_t n)
> >  	bool got_new_data;
> >  	void *sample;
> >  
> > +	err = ringbuf_validate(r);
> > +	if (err)
> > +		return err;
> 
> as Emil noted in first version, this seems like overkill, could you
> just check sample_cb != NULL before it's actualy called?
> 
> in [1] you mentioned you plan to add some feature that won't use sample_cb,
> it'd be easier to review/suggest the solution with more details on that
> 
> jirka

As-is it appears that the simplest thing to do is to error out in
ring_buffer__new() and ring_buffer__add() when callback is NULL or
when overwrite map flag is present.
I checked our internal usage for then __new/__add functions,
and it seems there are no cases when NULL is passed as a callback.

[...]

  reply	other threads:[~2026-06-19 21:12 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-19  0:26 [PATCH bpf v2 0/8] bpf: Fix ring buffer handling Tamir Duberstein
2026-06-19  0:26 ` [PATCH bpf v2 1/8] libbpf: ringbuf: Honor zero consume bounds Tamir Duberstein
2026-06-19 21:13   ` Eduard Zingerman
2026-06-19  0:26 ` [PATCH bpf v2 2/8] libbpf: ringbuf: Prevent NULL callback crash Tamir Duberstein
2026-06-19 13:54   ` Jiri Olsa
2026-06-19 21:11     ` Eduard Zingerman [this message]
2026-06-20  2:48       ` Alexei Starovoitov
2026-06-19  0:26 ` [PATCH bpf v2 3/8] libbpf: ringbuf: Reject overwrite callback use Tamir Duberstein
2026-06-19  0:26 ` [PATCH bpf v2 4/8] libbpf: ringbuf: Handle position counter wrap Tamir Duberstein
2026-06-19  0:41   ` sashiko-bot
2026-06-19  0:26 ` [PATCH bpf v2 5/8] bpf: ringbuf: Handle pending position wrap Tamir Duberstein
2026-06-19  0:45   ` sashiko-bot
2026-06-19  0:26 ` [PATCH bpf v2 6/8] bpf: user_ringbuf: Handle " Tamir Duberstein
2026-06-19  0:40   ` sashiko-bot
2026-06-19  0:26 ` [PATCH bpf v2 7/8] libbpf: ringbuf: Use compiler atomics Tamir Duberstein
2026-06-19  0:26 ` [PATCH bpf v2 8/8] libbpf: ringbuf: Prevent missed wakeups Tamir Duberstein
2026-06-20  1:53   ` Eduard Zingerman

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=130931685c8b2064325fc65a856ecd810c8a6b5c.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrea.righi@canonical.com \
    --cc=andrii@kernel.org \
    --cc=andriin@fb.com \
    --cc=arighi@nvidia.com \
    --cc=ast@kernel.org \
    --cc=awerner32@gmail.com \
    --cc=billy@starlabs.sg \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=emil@etsalapatis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=olsajiri@gmail.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=tamird@kernel.org \
    --cc=void@manifault.com \
    --cc=xukuohai@huawei.com \
    --cc=yonghong.song@linux.dev \
    --cc=zeffron@riotgames.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.