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:
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
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.