Commit c57c58a6 authored by Tomas Glozar's avatar Tomas Glozar Committed by Steven Rostedt (Google)
Browse files

rtla: Fix segfault in save_trace_to_file call

Running rtla with exit on threshold, but without saving trace leads to a
segmenetation fault:

$ rtla timerlat hist -T 10
...
Max timerlat IRQ latency from idle: 4.29 us in cpu 0
Segmentation fault

This is caused by null pointer deference in the call of
save_trace_to_file, which attempts to dereference an uninitialized
osnoise_tool variable:

save_trace_to_file(record->trace.inst, params->trace_output);
                   ^ this is uninitialized if params->trace_output is
                     not set

Fix this by not attempting to dereference "record" if it is NULL and
passing NULL instead. As a safety measure, the first field is also
checked for NULL inside save_trace_to_file.

Cc: John Kacur <jkacur@redhat.com>
Cc: Luis Goncalves <lgoncalv@redhat.com>
Cc: Costa Shulyupin <costa.shul@redhat.com>
Link: https://lore.kernel.org/20250313141034.299117-1-tglozar@redhat.com


Fixes: dc4d4e7c ("rtla: Refactor save_trace_to_file")
Signed-off-by: default avatarTomas Glozar <tglozar@redhat.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 814d051e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -983,7 +983,8 @@ int osnoise_hist_main(int argc, char *argv[])

	if (osnoise_trace_is_off(tool, record)) {
		printf("rtla osnoise hit stop tracing\n");
		save_trace_to_file(record->trace.inst, params->trace_output);
		save_trace_to_file(record ? record->trace.inst : NULL,
				   params->trace_output);
	}

out_hist:
+2 −1
Original line number Diff line number Diff line
@@ -813,7 +813,8 @@ int osnoise_top_main(int argc, char **argv)

	if (osnoise_trace_is_off(tool, record)) {
		printf("osnoise hit stop tracing\n");
		save_trace_to_file(record->trace.inst, params->trace_output);
		save_trace_to_file(record ? record->trace.inst : NULL,
				   params->trace_output);
	}

out_top:
+2 −1
Original line number Diff line number Diff line
@@ -1473,7 +1473,8 @@ int timerlat_hist_main(int argc, char *argv[])
		if (!params->no_aa)
			timerlat_auto_analysis(params->stop_us, params->stop_total_us);

		save_trace_to_file(record->trace.inst, params->trace_output);
		save_trace_to_file(record ? record->trace.inst : NULL,
				   params->trace_output);
	}

out_hist:
+2 −1
Original line number Diff line number Diff line
@@ -1295,7 +1295,8 @@ int timerlat_top_main(int argc, char *argv[])
		if (!params->no_aa)
			timerlat_auto_analysis(params->stop_us, params->stop_total_us);

		save_trace_to_file(record->trace.inst, params->trace_output);
		save_trace_to_file(record ? record->trace.inst : NULL,
				   params->trace_output);
	} else if (params->aa_only) {
		/*
		 * If the trace did not stop with --aa-only, at least print the
+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ int save_trace_to_file(struct tracefs_instance *inst, const char *filename)
	int out_fd, in_fd;
	int retval = -1;

	if (!filename)
	if (!inst || !filename)
		return 0;

	in_fd = tracefs_instance_file_open(inst, file, O_RDONLY);