Re: [PATCH v4 4/9] ring-buffer: Fix subbuf resize race in ring_buffer_alloc_read_page()

Vincent Donnefort <[email protected]>
Newsgroups org.kernel.vger.linux-trace-kernel,dev.linux.lists.sashiko-reviews
Message-ID <[email protected]>
On Wed, Aug 12, 2026 at 03:46:53PM +0000, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] The patch is an incomplete fix for a race condition in `ring_buffer_alloc_read_page()`. While it ensures newly allocated pages use `bpage->order`, it entirely misses the branch where `cpu_buffer->free_page` is reused. This allows an undersized cached page to be paired with a newer, larger `bpage->order`, leading to heap buffer overflows during reads and out-of-bounds frees when the page is released.
> --
> 
> --- Patch [4]: [PATCH v4 4/9] ring-buffer: Fix subbuf resize race in ring_buffer_alloc_read_page() ---
> commit 28754c82212e5979b25cf6fac815748ff021a277
> Author: Vincent Donnefort <[email protected]>
> 
> ring-buffer: Fix subbuf resize race in ring_buffer_alloc_read_page()
> 
> ring_buffer_alloc_read_page() is racy with ring_buffer_subbuf_order_set,
> it can allocate a reader page with an outdated order. This isn't a big
> issue, the user can still re-allocate a new reader page and try again.
> 
> However, what is more problematic is if the value of subbuf_order
> changes in the middle of ring_buffer_alloc_read_page(). In that case,
> bpage->order might not match the actual allocated memory.
> 
> Use bpage->order for the allocation to prevent this race.
> 
> > diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> > index 97449423d3a68..94552a433228d 100644
> > --- a/kernel/trace/ring_buffer.c
> > +++ b/kernel/trace/ring_buffer.c
> > @@ -7018,7 +7018,7 @@ ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
> >  	if (bpage->data) {
> >  		rb_init_data_page(bpage->data);
> 
> [Severity: High]
> This is a pre-existing issue, but does this path leave bpage->order
> mismatched with the actual allocation size of cpu_buffer->free_page?
> 
> If ring_buffer_subbuf_order_set() updates buffer->subbuf_order to a larger
> size before clearing cpu_buffer->free_page, ring_buffer_alloc_read_page()
> might read the new larger order into bpage->order, but then claim an older,
> smaller cpu_buffer->free_page:

Not sure I follow here. the whole point is to read subbuf_order only once and
then make sure we always refer to bpage->order and not subbuf_order. 

I believe this is just fixed in the following patch.

> 
> kernel/trace/ring_buffer.c:ring_buffer_alloc_read_page() {
>     ...
> 	bpage->order = order;
>     ...
> 	if (cpu_buffer->free_page) {
> 		bpage->data = cpu_buffer->free_page;
> 		cpu_buffer->free_page = NULL;
> 	}
>     ...
> }
> 
> Could this lead to an overflow of dpage->data when reading events?
> 
> kernel/trace/ring_buffer.c:ring_buffer_read_page() {
>     ...
> 			memcpy(dpage->data + pos, rpage->data + rpos, event_size);
>     ...
> }
> 
> It also appears this could cause an out-of-bounds free of bpage->data when
> the page is released, since it frees using the mismatched bpage->order
> instead of the page's actual allocation order.
> 
> Should we also verify the cached page's actual order matches bpage->order
> before claiming it?
> 
> >  	} else {
> > -		bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
> > +		bpage->data = alloc_cpu_data(cpu, bpage->order);
> >  		if (!bpage->data) {
> >  			kfree(bpage);
> >  			return ERR_PTR(-ENOMEM);
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4

-- 
Vincent
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.