• Ian Rogers's avatar
    libperf evsel: Make use of FD robust. · aba5daeb
    Ian Rogers authored
    FD uses xyarray__entry that may return NULL if an index is out of
    bounds. If NULL is returned then a segv happens as FD unconditionally
    dereferences the pointer. This was happening in a case of with perf
    iostat as shown below. The fix is to make FD an "int*" rather than an
    int and handle the NULL case as either invalid input or a closed fd.
    
      $ sudo gdb --args perf stat --iostat  list
      ...
      Breakpoint 1, perf_evsel__alloc_fd (evsel=0x5555560951a0, ncpus=1, nthreads=1) at evsel.c:50
      50      {
      (gdb) bt
       #0  perf_evsel__alloc_fd (evsel=0x5555560951a0, ncpus=1, nthreads=1) at evsel.c:50
       #1  0x000055555585c188 in evsel__open_cpu (evsel=0x5555560951a0, cpus=0x555556093410,
          threads=0x555556086fb0, start_cpu=0, end_cpu=1) at util/evsel.c:1792
       #2  0x000055555585cfb2 in evsel__open (evsel=0x5555560951a0, cpus=0x0, threads=0x555556086fb0)
          at util/evsel.c:2045
       #3  0x000055555585d0db in evsel__open_per_thread (evsel=0x5555560951a0, threads=0x555556086fb0)
          at util/evsel.c:2065
       #4  0x00005555558ece64 in create_perf_stat_counter (evsel=0x5555560951a0,
          config=0x555555c34700 <stat_config>, target=0x555555c2f1c0 <target>, cpu=0) at util/stat.c:590
       #5  0x000055555578e927 in __run_perf_stat (argc=1, argv=0x7fffffffe4a0, run_idx=0)
          at builtin-stat.c:833
       #6  0x000055555578f3c6 in run_perf_stat (argc=1, argv=0x7fffffffe4a0, run_idx=0)
          at builtin-stat.c:1048
       #7  0x0000555555792ee5 in cmd_stat (argc=1, argv=0x7fffffffe4a0) at builtin-stat.c:2534
       #8  0x0000555555835ed3 in run_builtin (p=0x555555c3f540 <commands+288>, argc=3,
          argv=0x7fffffffe4a0) at perf.c:313
       #9  0x0000555555836154 in handle_internal_command (argc=3, argv=0x7fffffffe4a0) at perf.c:365
       #10 0x000055555583629f in run_argv (argcp=0x7fffffffe2ec, argv=0x7fffffffe2e0) at perf.c:409
       #11 0x0000555555836692 in main (argc=3, argv=0x7fffffffe4a0) at perf.c:539
      ...
      (gdb) c
      Continuing.
      Error:
      The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (uncore_iio_0/event=0x83,umask=0x04,ch_mask=0xF,fc_mask=0x07/).
      /bin/dmesg | grep -i perf may provide additional information.
    
      Program received signal SIGSEGV, Segmentation fault.
      0x00005555559b03ea in perf_evsel__close_fd_cpu (evsel=0x5555560951a0, cpu=1) at evsel.c:166
      166                     if (FD(evsel, cpu, thread) >= 0)
    
    v3. fixes a bug in perf_evsel__run_ioctl where the sense of a branch was
        backward.
    Signed-off-by: default avatarIan Rogers <irogers@google.com>
    Acked-by: default avatarJiri Olsa <jolsa@redhat.com>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Stephane Eranian <eranian@google.com>
    Link: http://lore.kernel.org/lkml/20210918054440.2350466-1-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    aba5daeb
evsel.c 8.86 KB