* [PATCH 1/5] ring-buffer: Mask out the info bits when returning buffer page length
[not found] <20171227193307.929591859@goodmis.org>
@ 2017-12-27 19:33 ` Steven Rostedt
2017-12-27 19:33 ` [PATCH 2/5] tracing: Remove extra zeroing out of the ring buffer page Steven Rostedt
` (3 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2017-12-27 19:33 UTC (permalink / raw)
To: linux-kernel; +Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, stable
[-- Attachment #1: 0001-ring-buffer-Mask-out-the-info-bits-when-returning-bu.patch --]
[-- Type: text/plain, Size: 1941 bytes --]
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Two info bits were added to the "commit" part of the ring buffer data page
when returned to be consumed. This was to inform the user space readers that
events have been missed, and that the count may be stored at the end of the
page.
What wasn't handled, was the splice code that actually called a function to
return the length of the data in order to zero out the rest of the page
before sending it up to user space. These data bits were returned with the
length making the value negative, and that negative value was not checked.
It was compared to PAGE_SIZE, and only used if the size was less than
PAGE_SIZE. Luckily PAGE_SIZE is unsigned long which made the compare an
unsigned compare, meaning the negative size value did not end up causing a
large portion of memory to be randomly zeroed out.
Cc: stable@vger.kernel.org
Fixes: 66a8cb95ed040 ("ring-buffer: Add place holder recording of dropped events")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/ring_buffer.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index c87766c1c204..e06cde093f76 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -280,6 +280,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);
/* Missed count stored at end */
#define RB_MISSED_STORED (1 << 30)
+#define RB_MISSED_FLAGS (RB_MISSED_EVENTS|RB_MISSED_STORED)
+
struct buffer_data_page {
u64 time_stamp; /* page time stamp */
local_t commit; /* write committed index */
@@ -331,7 +333,9 @@ static void rb_init_page(struct buffer_data_page *bpage)
*/
size_t ring_buffer_page_len(void *page)
{
- return local_read(&((struct buffer_data_page *)page)->commit)
+ struct buffer_data_page *bpage = page;
+
+ return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS)
+ BUF_PAGE_HDR_SIZE;
}
--
2.13.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/5] tracing: Remove extra zeroing out of the ring buffer page
[not found] <20171227193307.929591859@goodmis.org>
2017-12-27 19:33 ` [PATCH 1/5] ring-buffer: Mask out the info bits when returning buffer page length Steven Rostedt
@ 2017-12-27 19:33 ` Steven Rostedt
2017-12-27 19:33 ` [PATCH 3/5] ring-buffer: Do no reuse reader page if still in use Steven Rostedt
` (2 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2017-12-27 19:33 UTC (permalink / raw)
To: linux-kernel; +Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, stable
[-- Attachment #1: 0002-tracing-Remove-extra-zeroing-out-of-the-ring-buffer-.patch --]
[-- Type: text/plain, Size: 1406 bytes --]
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
The ring_buffer_read_page() takes care of zeroing out any extra data in the
page that it returns. There's no need to zero it out again from the
consumer. It was removed from one consumer of this function, but
read_buffers_splice_read() did not remove it, and worse, it contained a
nasty bug because of it.
Cc: stable@vger.kernel.org
Fixes: 2711ca237a084 ("ring-buffer: Move zeroing out excess in page to ring buffer code")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/trace.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 59518b8126d0..73652d5318b2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6769,7 +6769,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
.spd_release = buffer_spd_release,
};
struct buffer_ref *ref;
- int entries, size, i;
+ int entries, i;
ssize_t ret = 0;
#ifdef CONFIG_TRACER_MAX_TRACE
@@ -6823,14 +6823,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
break;
}
- /*
- * zero out any left over data, this is going to
- * user land.
- */
- size = ring_buffer_page_len(ref->page);
- if (size < PAGE_SIZE)
- memset(ref->page + size, 0, PAGE_SIZE - size);
-
page = virt_to_page(ref->page);
spd.pages[i] = page;
--
2.13.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] ring-buffer: Do no reuse reader page if still in use
[not found] <20171227193307.929591859@goodmis.org>
2017-12-27 19:33 ` [PATCH 1/5] ring-buffer: Mask out the info bits when returning buffer page length Steven Rostedt
2017-12-27 19:33 ` [PATCH 2/5] tracing: Remove extra zeroing out of the ring buffer page Steven Rostedt
@ 2017-12-27 19:33 ` Steven Rostedt
2017-12-27 19:33 ` [PATCH 4/5] tracing: Fix crash when it fails to alloc ring buffer Steven Rostedt
2017-12-27 19:33 ` [PATCH 5/5] tracing: Fix possible double free on failure of allocating trace buffer Steven Rostedt
4 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2017-12-27 19:33 UTC (permalink / raw)
To: linux-kernel; +Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, stable
[-- Attachment #1: 0003-ring-buffer-Do-no-reuse-reader-page-if-still-in-use.patch --]
[-- Type: text/plain, Size: 1983 bytes --]
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
To free the reader page that is allocated with ring_buffer_alloc_read_page(),
ring_buffer_free_read_page() must be called. For faster performance, this
page can be reused by the ring buffer to avoid having to free and allocate
new pages.
The issue arises when the page is used with a splice pipe into the
networking code. The networking code may up the page counter for the page,
and keep it active while sending it is queued to go to the network. The
incrementing of the page ref does not prevent it from being reused in the
ring buffer, and this can cause the page that is being sent out to the
network to be modified before it is sent by reading new data.
Add a check to the page ref counter, and only reuse the page if it is not
being used anywhere else.
Cc: stable@vger.kernel.org
Fixes: 73a757e63114d ("ring-buffer: Return reader page back into existing ring buffer")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/ring_buffer.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index e06cde093f76..9ab18995ff1e 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -4404,8 +4404,13 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
{
struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
struct buffer_data_page *bpage = data;
+ struct page *page = virt_to_page(bpage);
unsigned long flags;
+ /* If the page is still in use someplace else, we can't reuse it */
+ if (page_ref_count(page) > 1)
+ goto out;
+
local_irq_save(flags);
arch_spin_lock(&cpu_buffer->lock);
@@ -4417,6 +4422,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
+ out:
free_page((unsigned long)bpage);
}
EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
--
2.13.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] tracing: Fix crash when it fails to alloc ring buffer
[not found] <20171227193307.929591859@goodmis.org>
` (2 preceding siblings ...)
2017-12-27 19:33 ` [PATCH 3/5] ring-buffer: Do no reuse reader page if still in use Steven Rostedt
@ 2017-12-27 19:33 ` Steven Rostedt
2017-12-27 19:33 ` [PATCH 5/5] tracing: Fix possible double free on failure of allocating trace buffer Steven Rostedt
4 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2017-12-27 19:33 UTC (permalink / raw)
To: linux-kernel
Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, stable, Jing Xia,
Chunyan Zhang
[-- Attachment #1: 0004-tracing-Fix-crash-when-it-fails-to-alloc-ring-buffer.patch --]
[-- Type: text/plain, Size: 2011 bytes --]
From: Jing Xia <jing.xia@spreadtrum.com>
Double free of the ring buffer happens when it fails to alloc new
ring buffer instance for max_buffer if TRACER_MAX_TRACE is configured.
The root cause is that the pointer is not set to NULL after the buffer
is freed in allocate_trace_buffers(), and the freeing of the ring
buffer is invoked again later if the pointer is not equal to Null,
as:
instance_mkdir()
|-allocate_trace_buffers()
|-allocate_trace_buffer(tr, &tr->trace_buffer...)
|-allocate_trace_buffer(tr, &tr->max_buffer...)
// allocate fail(-ENOMEM),first free
// and the buffer pointer is not set to null
|-ring_buffer_free(tr->trace_buffer.buffer)
// out_free_tr
|-free_trace_buffers()
|-free_trace_buffer(&tr->trace_buffer);
//if trace_buffer is not null, free again
|-ring_buffer_free(buf->buffer)
|-rb_free_cpu_buffer(buffer->buffers[cpu])
// ring_buffer_per_cpu is null, and
// crash in ring_buffer_per_cpu->pages
Link: http://lkml.kernel.org/r/20171226071253.8968-1-chunyan.zhang@spreadtrum.com
Cc: stable@vger.kernel.org
Fixes: 737223fbca3b1 ("tracing: Consolidate buffer allocation code")
Signed-off-by: Jing Xia <jing.xia@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/trace.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 73652d5318b2..0e53d46544b8 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7603,7 +7603,9 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
allocate_snapshot ? size : 1);
if (WARN_ON(ret)) {
ring_buffer_free(tr->trace_buffer.buffer);
+ tr->trace_buffer.buffer = NULL;
free_percpu(tr->trace_buffer.data);
+ tr->trace_buffer.data = NULL;
return -ENOMEM;
}
tr->allocated_snapshot = allocate_snapshot;
--
2.13.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] tracing: Fix possible double free on failure of allocating trace buffer
[not found] <20171227193307.929591859@goodmis.org>
` (3 preceding siblings ...)
2017-12-27 19:33 ` [PATCH 4/5] tracing: Fix crash when it fails to alloc ring buffer Steven Rostedt
@ 2017-12-27 19:33 ` Steven Rostedt
4 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2017-12-27 19:33 UTC (permalink / raw)
To: linux-kernel
Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, stable, Jing Xia,
Chunyan Zhang
[-- Attachment #1: 0005-tracing-Fix-possible-double-free-on-failure-of-alloc.patch --]
[-- Type: text/plain, Size: 1200 bytes --]
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Jing Xia and Chunyan Zhang reported that on failing to allocate part of the
tracing buffer, memory is freed, but the pointers that point to them are not
initialized back to NULL, and later paths may try to free the freed memory
again. Jing and Chunyan fixed one of the locations that does this, but
missed a spot.
Link: http://lkml.kernel.org/r/20171226071253.8968-1-chunyan.zhang@spreadtrum.com
Cc: stable@vger.kernel.org
Fixes: 737223fbca3b1 ("tracing: Consolidate buffer allocation code")
Reported-by: Jing Xia <jing.xia@spreadtrum.com>
Reported-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/trace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 0e53d46544b8..2a8d8a294345 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7580,6 +7580,7 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size
buf->data = alloc_percpu(struct trace_array_cpu);
if (!buf->data) {
ring_buffer_free(buf->buffer);
+ buf->buffer = NULL;
return -ENOMEM;
}
--
2.13.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-12-27 19:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20171227193307.929591859@goodmis.org>
2017-12-27 19:33 ` [PATCH 1/5] ring-buffer: Mask out the info bits when returning buffer page length Steven Rostedt
2017-12-27 19:33 ` [PATCH 2/5] tracing: Remove extra zeroing out of the ring buffer page Steven Rostedt
2017-12-27 19:33 ` [PATCH 3/5] ring-buffer: Do no reuse reader page if still in use Steven Rostedt
2017-12-27 19:33 ` [PATCH 4/5] tracing: Fix crash when it fails to alloc ring buffer Steven Rostedt
2017-12-27 19:33 ` [PATCH 5/5] tracing: Fix possible double free on failure of allocating trace buffer Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).