]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rtla: Fix segfault in save_trace_to_file call
authorTomas Glozar <tglozar@redhat.com>
Thu, 13 Mar 2025 14:10:34 +0000 (15:10 +0100)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Wed, 26 Mar 2025 14:35:20 +0000 (10:35 -0400)
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: dc4d4e7c72d1 ("rtla: Refactor save_trace_to_file")
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
tools/tracing/rtla/src/osnoise_hist.c
tools/tracing/rtla/src/osnoise_top.c
tools/tracing/rtla/src/timerlat_hist.c
tools/tracing/rtla/src/timerlat_top.c
tools/tracing/rtla/src/trace.c

index 7c6ef67ef3e6ca52eac84f8dfc641517b89baa19..f4c9051c33c4db0e4ebad5840f50e30e1ebd5041 100644 (file)
@@ -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:
index 0eeefbbbf317361126ed01fabff15de31f4303a5..dacec2f990177aab607ddfcf65fe2e342e62e338 100644 (file)
@@ -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:
index 93d0c9e450204b5dd172ba14b3da9625cd75db0d..822c068b477672b8bc35d22473ce7acfe1a217d9 100644 (file)
@@ -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:
index 3894ac37d81ca43fa547ce7f0083cd9607a0f133..c3196a0bb5851bf3c883959b3c5986acc44d0607 100644 (file)
@@ -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
index 74ed2f6208baa3ecd71ae549e9bb755d27c9ca0f..69cbc48d53d3a982b15c43f536c2d235b1e4063e 100644 (file)
@@ -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);