[2.6.33] ring-buffer: urgent changes
Subsystems (2)
Steven Rostedt
maintainerIngo,
Please pull the latest tip/tracing/urgent tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/urgent
David Sharp (1):
ring-buffer: Wrap a list.next reference with rb_list_head()
Steven Rostedt (1):
ring-buffer: Add rb_list_head() wrapper around new reader page next field
----
kernel/trace/ring_buffer.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
Steven Rostedt
maintainerPATCH 1/2 ring-buffer: Wrap a list.next reference with rb_list_head()
From: David Sharp <[email protected]>
This reference at the end of rb_get_reader_page() was causing off-by-one writes to the prev pointer of the page after the reader page when that page is the head page, and therefore the reader page has the RB_PAGE_HEAD flag in its list.next pointer. This eventually results in a GPF in a subsequent call to rb_set_head_page() (usually from rb_get_reader_page()) when that prev pointer is dereferenced. The dereferenced register would characteristically have an address that appears shifted left by one byte (eg, ffxxxxxxxxxxxxyy instead of ffffxxxxxxxxxxxx) due to being written at an address one byte too high.
LKML-Reference: <[email protected]>
--- kernel/trace/ring_buffer.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/trace/ring_buffer.c +1 -1
@@ -2906,7 +2906,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)* * Now make the new head point back to the reader page. */ - reader->list.next->prev = &cpu_buffer->reader_page->list; +rb_list_head (reader->list.next)->prev = &cpu_buffer->reader_page->list;rb_inc_page (cpu_buffer, &cpu_buffer->head_page);/* Finally update the reader page to the new head */
Signature · 1 line
1.6.5
Steven Rostedt
maintainerPATCH 2/2 ring-buffer: Add rb_list_head() wrapper around new reader page next field
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
If the very unlikely case happens where the writer moves the head by one between where the head page is read and where the new reader page is assigned _and_ the writer then writes and wraps the entire ring buffer so that the head page is back to what was originally read as the head page, the page to be swapped will have a corrupted next pointer.
Simple solution is to wrap the assignment of the next pointer with a rb_list_head().
--- kernel/trace/ring_buffer.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/trace/ring_buffer.c +1 -1
@@ -2869,7 +2869,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)* Splice the empty reader page into the list around the head. */ reader =rb_set_head_page (cpu_buffer); - cpu_buffer->reader_page->list.next = reader->list.next; + cpu_buffer->reader_page->list.next =rb_list_head (reader->list.next); cpu_buffer->reader_page->list.prev = reader->list.prev;/*
Signature · 1 line
1.6.5
Quoted 12 lines · Steven Rostedt
Ingo,
Please pull the latest tip/tracing/urgent tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/urgentDavid Sharp (1):
ring-buffer: Wrap a list.next reference withrb_list_head()
Quoted 6 lines
Steven Rostedt (1):
ring-buffer: Addrb_list_head()wrapper around new reader page next field----
kernel/trace/ring_buffer.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
Pulled, thanks a lot Steve!
Ingo