Linux Trace Kernel
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Vincent Donnefort" <vdonnefort@google.com>
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH v4 3/9] ring-buffer: Fix subbuf resize race with ring buffer readers
Date: Wed, 12 Aug 2026 15:53:12 +0000	[thread overview]
Message-ID: <20260812155312.ADF031F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260812153311.2328812-4-vdonnefort@google.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Use-After-Free dereference of `reader_page` in `ring_buffer_read_start()` when bypassing buffer mutex.

Pre-existing issues:
- [High] 32-bit integer overflow in ring buffer capacity calculation truncates large trace buffers.
- [High] Out-of-bounds kernel memory write and VMAP flush in `ring_buffer_map_get_reader()` due to global capacity TOCTOU race.
--

--- Patch [3]: [PATCH v4 3/9] ring-buffer: Fix subbuf resize race with ring buffer readers ---
commit 9618f28d9a6939c645e7579fa798c42557eb075c
Author: Vincent Donnefort <vdonnefort@google.com>

ring-buffer: Fix subbuf resize race with ring buffer readers

This commit changes the trace_buffer to use bpage order instead of
trace_buffer::subbuf_size in ring_buffer_read_start() and
ring_buffer_read_page(). It also removes trace_buffer::subbuf_size and
introduces capacity accessors.

> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index ec4f5a0c93e85..97449423d3a68 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
[ ... ]
> @@ -6380,36 +6417,44 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume);
>  struct ring_buffer_iter *
>  ring_buffer_read_start(struct trace_buffer *buffer, int cpu, gfp_t flags)
>  {
> +	struct ring_buffer_iter *iter __free(kfree) = kzalloc_obj(*iter, flags);
>  	struct ring_buffer_per_cpu *cpu_buffer;
> -	struct ring_buffer_iter *iter;
> -
> -	if (!cpumask_test_cpu(cpu, buffer->cpumask))
> -		return NULL;
>  
> -	iter = kzalloc_obj(*iter, flags);
>  	if (!iter)
>  		return NULL;
>  
> -	/* Holds the entire event: data and meta data */
> -	iter->event_size = buffer->subbuf_size;
> -	iter->event = kmalloc(iter->event_size, flags);
> -	if (!iter->event) {
> -		kfree(iter);
> +	if (!cpumask_test_cpu(cpu, buffer->cpumask))
>  		return NULL;
> -	}
>  
>  	cpu_buffer = buffer->buffers[cpu];
>  
> -	iter->cpu_buffer = cpu_buffer;
> +	/*
> +	 * Only KDB is using GFP_ATOMIC, for the others, lock the buffer to
> +	 * prevent concurrent resizing.
> +	 */
> +	if (gfpflags_allow_blocking(flags))
> +		mutex_lock(&buffer->mutex);
>  
>  	atomic_inc(&cpu_buffer->resize_disabled);
>  
> +	if (gfpflags_allow_blocking(flags))
> +		mutex_unlock(&buffer->mutex);
> +
> +	/* Holds the entire event: data and meta data. */
> +	iter->event_size = rb_page_capacity(READ_ONCE(cpu_buffer->reader_page));

[Severity: High]
Can this result in a use-after-free dereference of the reader page?

When ring_buffer_read_start() is called with GFP_ATOMIC, it skips acquiring
buffer->mutex and only increments cpu_buffer->resize_disabled.

If a concurrent ring_buffer_subbuf_order_set() has already passed its
resize_disabled check, it will proceed to allocate new pages and free the old
reader page.

A thread executing ring_buffer_read_start() could load the old reader page
pointer just before it is freed by the other CPU, dereferencing freed memory
when accessing the order field.

> +	iter->event = kmalloc(iter->event_size, flags);
> +	if (!iter->event) {
> +		atomic_dec(&cpu_buffer->resize_disabled);
> +		return NULL;
> +	}
[ ... ]
> @@ -7367,8 +7413,8 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
>  		}
>  
>  		/* Update the number of pages to match the new size */
> -		nr_pages = old_size * buffer->buffers[cpu]->nr_pages;
> -		nr_pages = DIV_ROUND_UP(nr_pages, buffer->subbuf_size);
> +		nr_pages = old_capacity * buffer->buffers[cpu]->nr_pages;

[Severity: High]
This is a pre-existing issue, but can this 32-bit integer capacity calculation
truncate large trace buffers?

For buffers larger than 4GB, the multiplication of old_capacity and
buffer->buffers[cpu]->nr_pages can exceed 32 bits. Because nr_pages is a
32-bit signed integer, the result is truncated, and the buffer is shrunk to a
tiny fraction of its intended size during a resize operation.

> +		nr_pages = DIV_ROUND_UP(nr_pages, rb_subbuf_capacity(buffer));
>  
>  		/* we need a minimum of two pages */
>  		if (nr_pages < 2)
[ ... ]
> @@ -7896,7 +7941,7 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu)
>  			 * missed events, then record it there.
>  			 */
>  			commit = rb_page_size(reader);
> -			if (buffer->subbuf_size - commit >= sizeof(missed_events)) {
> +			if (rb_subbuf_capacity(buffer) - commit >= sizeof(missed_events)) {

[Severity: High]
This is a pre-existing issue, but does this create a time-of-check to
time-of-use race leading to an out-of-bounds kernel memory write and
VMAP flush?

During a sub-buffer order resize, ring_buffer_subbuf_order_set() modifies
buffer->subbuf_order globally before verifying if resize_disabled is set. If
the buffer is currently mapped, the resize aborts and restores the old order.

In that race window, a concurrent ring_buffer_map_get_reader() call will see
the new, larger capacity via rb_subbuf_capacity(buffer) here. It could then
write missed_events past the end of the old, smaller reader page, and
subsequently flush memory beyond the mapped VMAP range.

>  				memcpy(&dpage->data[commit], &missed_events,
>  				       sizeof(missed_events));
>  				local_add(RB_MISSED_STORED, &dpage->commit);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260812153311.2328812-1-vdonnefort@google.com?part=3

  reply	other threads:[~2026-08-12 15:53 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 15:33 [PATCH v4 0/9] ring-buffer: Fixes for subbuf resizing and persistent buffers Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 1/9] ring-buffer: Free cpu_buffer->free_page with subbuf_order Vincent Donnefort
2026-08-12 15:50   ` sashiko-bot
2026-08-12 16:37     ` Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 2/9] ring-buffer: Hold cpu_buffer::lock when resizing a subbuf Vincent Donnefort
2026-08-12 15:46   ` sashiko-bot
2026-08-12 16:41     ` Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 3/9] ring-buffer: Fix subbuf resize race with ring buffer readers Vincent Donnefort
2026-08-12 15:53   ` sashiko-bot [this message]
2026-08-12 16:44     ` Vincent Donnefort
2026-08-12 17:24       ` Steven Rostedt
2026-08-12 15:33 ` [PATCH v4 4/9] ring-buffer: Fix subbuf resize race in ring_buffer_alloc_read_page() Vincent Donnefort
2026-08-12 15:46   ` sashiko-bot
2026-08-12 16:50     ` Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 5/9] tracing: Fix subbuf resize races in trace_pipe_raw readers Vincent Donnefort
2026-08-12 15:47   ` sashiko-bot
2026-08-12 16:57     ` Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 6/9] ring-buffer: Dynamically calculate max_data_size Vincent Donnefort
2026-08-12 15:56   ` sashiko-bot
2026-08-12 17:12     ` Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 7/9] ring-buffer: Remove trace_buffer::cpus Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 8/9] ring-buffer: Remove ring_buffer_per_cpu::mapped Vincent Donnefort
2026-08-12 15:33 ` [PATCH v4 9/9] ring-buffer: Make nr_pages unsigned int Vincent Donnefort
2026-08-12 15:47   ` sashiko-bot
2026-08-12 17:15     ` Vincent Donnefort

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=20260812155312.ADF031F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vdonnefort@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox