Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf record: Fix a segfault in record__read_lost_samples()

When it fails to open events record__open() returns without setting the
session->evlist. Then it gets a segfault in the function trying to read
lost sample counts. You can easily reproduce it as a normal user like:

$ perf record -p 1 true
...
perf: Segmentation fault
...

Skip the function if it has no evlist. And add more protection for evsels
which are not properly initialized.

Fixes: a49aa8a54e861af1 ("perf record: Read and inject LOST_SAMPLES events")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Leo Yan <leo.yan@linaro.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20220909235024.278281-1-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
d031a00a dc64641c

+6
+6
tools/perf/builtin-record.c
··· 1888 1888 struct perf_record_lost_samples *lost; 1889 1889 struct evsel *evsel; 1890 1890 1891 + /* there was an error during record__open */ 1892 + if (session->evlist == NULL) 1893 + return; 1894 + 1891 1895 lost = zalloc(PERF_SAMPLE_MAX_SIZE); 1892 1896 if (lost == NULL) { 1893 1897 pr_debug("Memory allocation failed\n"); ··· 1903 1899 evlist__for_each_entry(session->evlist, evsel) { 1904 1900 struct xyarray *xy = evsel->core.sample_id; 1905 1901 1902 + if (xy == NULL || evsel->core.fd == NULL) 1903 + continue; 1906 1904 if (xyarray__max_x(evsel->core.fd) != xyarray__max_x(xy) || 1907 1905 xyarray__max_y(evsel->core.fd) != xyarray__max_y(xy)) { 1908 1906 pr_debug("Unmatched FD vs. sample ID: skip reading LOST count\n");