Skip to content

Commit 9366c1b

Browse files
Steven Rostedtrostedt
Steven Rostedt
authored andcommitted
ring-buffer: Fix race between integrity check and readers
The function rb_check_pages() was added to make sure the ring buffer's pages were sane. This check is done when the ring buffer size is modified as well as when the iterator is released (closing the "trace" file), as that was considered a non fast path and a good place to do a sanity check. The problem is that the check does not have any locks around it. If one process were to read the trace file, and another were to read the raw binary file, the check could happen while the reader is reading the file. The issues with this is that the check requires to clear the HEAD page before doing the full check and it restores it afterward. But readers require the HEAD page to exist before it can read the buffer, otherwise it gives a nasty warning and disables the buffer. By adding the reader lock around the check, this keeps the race from happening. Cc: [email protected] # 3.6 Signed-off-by: Steven Rostedt <[email protected]>
1 parent 54f7be5 commit 9366c1b

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

kernel/trace/ring_buffer.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3783,12 +3783,17 @@ void
37833783
ring_buffer_read_finish(struct ring_buffer_iter *iter)
37843784
{
37853785
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
3786+
unsigned long flags;
37863787

37873788
/*
37883789
* Ring buffer is disabled from recording, here's a good place
3789-
* to check the integrity of the ring buffer.
3790+
* to check the integrity of the ring buffer.
3791+
* Must prevent readers from trying to read, as the check
3792+
* clears the HEAD page and readers require it.
37903793
*/
3794+
raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
37913795
rb_check_pages(cpu_buffer);
3796+
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
37923797

37933798
atomic_dec(&cpu_buffer->record_disabled);
37943799
atomic_dec(&cpu_buffer->buffer->resize_disabled);

0 commit comments

Comments
 (0)