On Sat, Sep 12, 2026 at 11:39:38AM +0100, David Carlier wrote:
> ring_buffer_subbuf_order_set() stores the new order and only then walks
> the CPUs, returning -EBUSY if any of them has resizing disabled. A user
> mapped buffer has resizing disabled, and __rb_map_vma() reads
> buffer->subbuf_order without buffer->mutex, so an mmap of an already
> mapped CPU racing the failing order change sizes the mapping with the
> new order and inserts pages past the sub-buffer into the VMA.
>
> Check the CPUs before storing the new order.
>
> Fixes: 117c39200d9d ("ring-buffer: Introducing ring-buffer mapping functions")
> Cc: [email protected]
> Signed-off-by: David Carlier <[email protected]>
> ---
> kernel/trace/ring_buffer.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index 9c03a555a6ba..d7e5e4620d09 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -7474,6 +7474,14 @@ int ring_buffer_subbuf_order_set(struct trace_buffer
> *buffer, int order)
>
> old_capacity = rb_subbuf_capacity(buffer);
>
> + /* The mmap fast path reads subbuf_order without buffer->mutex. */
> + for_each_buffer_cpu(buffer, cpu) {
> + if (!cpumask_test_cpu(cpu, buffer->cpumask))
> + continue;
> + if (atomic_read(&buffer->buffers[cpu]->resize_disabled))
> + return -EBUSY;
> + }
> +
> atomic_inc(&buffer->record_disabled);
>
> /* Make sure all commits have finished */
> --
> 2.55.0
>
I do not think this is correct.
__rb_map_vma() reads subbuf_order without the the buffer lock __only__ if it is
already ->user_mapped, which means it has already the resized disabled.
During the first setup, it takes buffer->mutex.
--
Vincent