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.

Fixes: dc4d4e7c72d1 ("rtla: Refactor save_trace_to_file")
Signed-off-by: Tomas Glozar <tglo...@redhat.com>
---
Note: As this fixes a commit in linux-next, the Fixes commit ID might
have to be adjusted.

 tools/tracing/rtla/src/osnoise_hist.c  | 3 ++-
 tools/tracing/rtla/src/osnoise_top.c   | 3 ++-
 tools/tracing/rtla/src/timerlat_hist.c | 3 ++-
 tools/tracing/rtla/src/timerlat_top.c  | 3 ++-
 tools/tracing/rtla/src/trace.c         | 2 +-
 5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tools/tracing/rtla/src/osnoise_hist.c 
b/tools/tracing/rtla/src/osnoise_hist.c
index 7c6ef67ef3e6..f4c9051c33c4 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -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:
diff --git a/tools/tracing/rtla/src/osnoise_top.c 
b/tools/tracing/rtla/src/osnoise_top.c
index 0eeefbbbf317..dacec2f99017 100644
--- a/tools/tracing/rtla/src/osnoise_top.c
+++ b/tools/tracing/rtla/src/osnoise_top.c
@@ -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:
diff --git a/tools/tracing/rtla/src/timerlat_hist.c 
b/tools/tracing/rtla/src/timerlat_hist.c
index 93d0c9e45020..822c068b4776 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -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:
diff --git a/tools/tracing/rtla/src/timerlat_top.c 
b/tools/tracing/rtla/src/timerlat_top.c
index 3894ac37d81c..c3196a0bb585 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -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
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index 74ed2f6208ba..69cbc48d53d3 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -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);
-- 
2.48.1


Reply via email to