Skip to contentSkip to conversation

tracing: Fixes for v7.2

PATCH New Steven Rostedt 1 participant 6 messages Jul 29

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover tracing: Fixes for v7.2

tracing fixes for 7.2:

- Reset dropped_count in mmio_reset_data()

When mmio_reset_data() is called, it does not reset the dropped_count so that subsequent runs will have incorrect reporting.

- Add NULL check for mmio_trace_array in logging functions

The functions __trace_mmiotrace_rw() and __trace_mmiotrace_map() may have the 'tr' variable passed to it as NULL. But they both dereference it without checking if it is NULL first.

- Check return value of __register_event() in trace_module_add_events()

If __register_event() fails, the call after it (__add_event_to_tracers()) will create a file for it. If the module fails to load and its memory is freed, the file will still point to it and it will not be removed as the registering of the event did not complete. Only call __add_event_to_tracers() if the __register_event() was successful.

- Fix false positive match in regex_match_full()

The regex full matching uses a strncmp() to test against the match string and the value. It should not match if value is a prefix of the string to match. Check to make sure the length of the strings match before comparing.

- Fix reader page read offset for remote buffers

A page swapped in by __rb_get_reader_page_from_remote() retains its stale read offset, causing subsequent reads to skip events or read past valid data.

git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace/fixes

Head SHA1: 78cd56c2a9d2e8da763cea3b06b636266ca66911

Masami Hiramatsu (Google) (4):
tracing/mmiotrace: Reset dropped_count in mmio_reset_data() tracing/mmiotrace: Add NULL check for mmio_trace_array in logging functions
tracing: Check return value of __register_event() in trace_module_add_events() tracing/filters: Fix false positive match in regex_match_full()

Vincent Donnefort (1):
ring-buffer: Fix reader page read offset for remote buffers

----

 kernel/trace/ring_buffer.c         |  1 +
 kernel/trace/trace_events.c        |  4 ++--
 kernel/trace/trace_events_filter.c |  3 +++
 kernel/trace/trace_mmiotrace.c     | 13 +++++++++++--
 4 files changed, 17 insertions(+), 4 deletions(-)
#1 lore raw

PATCH 1/5 tracing/mmiotrace: Reset dropped_count in mmio_reset_data()

From: "Masami Hiramatsu (Google)" <[email protected]>

mmio_reset_data() is called during tracer initialization, reset, and start. While it resets overrun_detected and prev_overruns, it neglects to reset dropped_count. Consequently, dropped event counts from prior tracing sessions persist in dropped_count and corrupt overrun reports in subsequent runs.

Fix this by explicitly calling atomic_set(&dropped_count, 0) in mmio_reset_data().

Fixes 173ed24ee2d6 ("mmiotrace: count events lost due to not recording")
Assisted-by Antigravity:gemini-3.6-flash
---
 kernel/trace/trace_mmiotrace.c | 1 +
 1 file changed, 1 insertion(+)
kernel/trace/trace_mmiotrace.c +1 -0
index b88b8d9923ad..e064ba3f28cb 100644
@@ -29,6 +29,7 @@ static void mmio_reset_data(struct trace_array *tr)
 {
 	overrun_detected = false;
 	prev_overruns = 0;
+	atomic_set(&dropped_count, 0);
 
 	tracing_reset_online_cpus(&tr->array_buffer);
 }
Signature · 1 line
2.53.0
#2 lore raw

PATCH 2/5 tracing/mmiotrace: Add NULL check for mmio_trace_array in logging functions

In reply to Steven Rostedt

From: "Masami Hiramatsu (Google)" <[email protected]>

mmio_trace_rw() and mmio_trace_mapping() retrieve mmio_trace_array into tr and pass it to __trace_mmiotrace_rw() and __trace_mmiotrace_map(). If these functions are invoked while mmio_trace_array is NULL (e.g. before initialization or after disabled), accessing tr->array_buffer.buffer will result in a NULL pointer dereference crash.

Fix this by adding an explicit NULL check for tr at the beginning of __trace_mmiotrace_rw() and __trace_mmiotrace_map().

Fixes f984b51e0779 ("ftrace: add mmiotrace plugin")
Assisted-by Antigravity:gemini-3.6-flash
---
 kernel/trace/trace_mmiotrace.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/trace/trace_mmiotrace.c +10 -2
index e064ba3f28cb..df8692c2dea8 100644
@@ -294,11 +294,15 @@ device_initcall(init_mmio_trace);
 static void __trace_mmiotrace_rw(struct trace_array *tr,
 				struct mmiotrace_rw *rw)
 {
-	struct trace_buffer *buffer = tr->array_buffer.buffer;
+	struct trace_buffer *buffer;
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_rw *entry;
 	unsigned int trace_ctx;
 
+	if (!tr)
+		return;
+
+	buffer = tr->array_buffer.buffer;
 	trace_ctx = tracing_gen_ctx_flags(0);
 	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW,
 					  sizeof(*entry), trace_ctx);
@@ -321,11 +325,15 @@ void mmio_trace_rw(struct mmiotrace_rw *rw)
 static void __trace_mmiotrace_map(struct trace_array *tr,
 				struct mmiotrace_map *map)
 {
-	struct trace_buffer *buffer = tr->array_buffer.buffer;
+	struct trace_buffer *buffer;
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_map *entry;
 	unsigned int trace_ctx;
 
+	if (!tr)
+		return;
+
+	buffer = tr->array_buffer.buffer;
 	trace_ctx = tracing_gen_ctx_flags(0);
 	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP,
 					  sizeof(*entry), trace_ctx);
Signature · 1 line
2.53.0
#3 lore raw

PATCH 3/5 tracing: Check return value of __register_event() in trace_module_add_events()

In reply to Steven Rostedt

From: "Masami Hiramatsu (Google)" <[email protected]>

trace_module_add_events() ignores the return value of __register_event() and unconditionally calls __add_event_to_tracers() for each event.

If __register_event() fails (for example, if event_init() fails), the trace_event_call is not added to ftrace_events list, but __add_event_to_tracers() still creates a trace_event_file pointing to it. If module loading subsequently fails and module memory is freed, tracing state retains a stale trace_event_call pointer in trace_event_file, leading to a use-after-free when tracefs or tracing subsystem operations are later executed.

Fix this by checking the return value of __register_event() and only calling __add_event_to_tracers() if event registration succeeded.

Fixes ae63b31e4d0e ("tracing: Separate out trace events from global variables")
Assisted-by Antigravity:gemini-3.5-flash
---
 kernel/trace/trace_events.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace_events.c +2 -2
index 956692856fa8..c01b10b99f67 100644
@@ -3933,8 +3933,8 @@ static void trace_module_add_events(struct module *mod)
 	end = mod->trace_events + mod->num_trace_events;
 
 	for_each_event(call, start, end) {
-		__register_event(*call, mod);
-		__add_event_to_tracers(*call);
+		if (!__register_event(*call, mod))
+			__add_event_to_tracers(*call);
 	}
 
 	update_cache_events(mod);
Signature · 1 line
2.53.0
#4 lore raw

PATCH 4/5 tracing/filters: Fix false positive match in regex_match_full()

In reply to Steven Rostedt

From: "Masami Hiramatsu (Google)" <[email protected]>

regex_match_full() calls strncmp(str, r->pattern, len) where len is the target field buffer size. When len is smaller than r->len (the filter pattern length), strncmp() checks only len bytes of r->pattern against str. If those len bytes match, strncmp() returns 0, resulting in a false-positive match where a shorter string in a fixed-size field matches a longer filter pattern.

For example, a 4-byte static string field containing "abcd" matched the filter pattern "abcdefgh" because strncmp("abcd", "abcdefgh", 4) returned 0. In this case, @len does NOT include '\0' because it is fixed-size array.

Fix this by returning 0 (no match) early when len < r->len.

Fixes 1889d20922d1 ("tracing/filters: Provide basic regex support")
Assisted-by Antigravity:gemini-3.5-flash
---
 kernel/trace/trace_events_filter.c | 3 +++
 1 file changed, 3 insertions(+)
kernel/trace/trace_events_filter.c +3 -0
index 6385cd662d8d..2b46ca536045 100644
@@ -1027,6 +1027,9 @@ static int regex_match_full(char *str, struct regex *r, int len)
 	if (!len)
 		return strcmp(str, r->pattern) == 0;
 
+	if (len < r->len)
+		return 0;
+
 	return strncmp(str, r->pattern, len) == 0;
 }
 
Signature · 1 line
2.53.0
#5 lore raw

PATCH 5/5 ring-buffer: Fix reader page read offset for remote buffers

In reply to Steven Rostedt

From: Vincent Donnefort <[email protected]>

A page swapped in by __rb_get_reader_page_from_remote() retains its stale read offset, causing subsequent reads to skip events or read past valid data. Fix it.

Fixes fbd1743ecba1 ("ring-buffer: Add non-consuming read for ring-buffer remotes")
---
 kernel/trace/ring_buffer.c | 1 +
 1 file changed, 1 insertion(+)
kernel/trace/ring_buffer.c +1 -0
index 804ccae694d2..78d3875a47a5 100644
@@ -5783,6 +5783,7 @@ __rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer)
 
 	cpu_buffer->head_page = new_head;
 	cpu_buffer->reader_page = new_reader;
+	cpu_buffer->reader_page->read = 0;
 	cpu_buffer->pages = &new_head->list;
 	cpu_buffer->read_stamp = new_reader->page->time_stamp;
 	cpu_buffer->lost_events = cpu_buffer->meta_page->reader.lost_events;
Signature · 1 line
2.53.0