Star64_linux/kernel/trace
Zheng Yejian 235c03df2c tracing: Fix memleak due to race between current_tracer and trace
[ Upstream commit eecb91b9f9 ]

Kmemleak report a leak in graph_trace_open():

  unreferenced object 0xffff0040b95f4a00 (size 128):
    comm "cat", pid 204981, jiffies 4301155872 (age 99771.964s)
    hex dump (first 32 bytes):
      e0 05 e7 b4 ab 7d 00 00 0b 00 01 00 00 00 00 00 .....}..........
      f4 00 01 10 00 a0 ff ff 00 00 00 00 65 00 10 00 ............e...
    backtrace:
      [<000000005db27c8b>] kmem_cache_alloc_trace+0x348/0x5f0
      [<000000007df90faa>] graph_trace_open+0xb0/0x344
      [<00000000737524cd>] __tracing_open+0x450/0xb10
      [<0000000098043327>] tracing_open+0x1a0/0x2a0
      [<00000000291c3876>] do_dentry_open+0x3c0/0xdc0
      [<000000004015bcd6>] vfs_open+0x98/0xd0
      [<000000002b5f60c9>] do_open+0x520/0x8d0
      [<00000000376c7820>] path_openat+0x1c0/0x3e0
      [<00000000336a54b5>] do_filp_open+0x14c/0x324
      [<000000002802df13>] do_sys_openat2+0x2c4/0x530
      [<0000000094eea458>] __arm64_sys_openat+0x130/0x1c4
      [<00000000a71d7881>] el0_svc_common.constprop.0+0xfc/0x394
      [<00000000313647bf>] do_el0_svc+0xac/0xec
      [<000000002ef1c651>] el0_svc+0x20/0x30
      [<000000002fd4692a>] el0_sync_handler+0xb0/0xb4
      [<000000000c309c35>] el0_sync+0x160/0x180

The root cause is descripted as follows:

  __tracing_open() {  // 1. File 'trace' is being opened;
    ...
    *iter->trace = *tr->current_trace;  // 2. Tracer 'function_graph' is
                                        //    currently set;
    ...
    iter->trace->open(iter);  // 3. Call graph_trace_open() here,
                              //    and memory are allocated in it;
    ...
  }

  s_start() {  // 4. The opened file is being read;
    ...
    *iter->trace = *tr->current_trace;  // 5. If tracer is switched to
                                        //    'nop' or others, then memory
                                        //    in step 3 are leaked!!!
    ...
  }

To fix it, in s_start(), close tracer before switching then reopen the
new tracer after switching. And some tracers like 'wakeup' may not update
'iter->private' in some cases when reopen, then it should be cleared
to avoid being mistakenly closed again.

Link: https://lore.kernel.org/linux-trace-kernel/20230817125539.1646321-1-zhengyejian1@huawei.com

Fixes: d7350c3f45 ("tracing/core: make the read callbacks reentrants")
Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-09-05 01:25:05 +08:00
..
blktrace.c trace/blktrace: fix memory leak with using debugfs_lookup() 2023-04-19 18:00:08 +08:00
bpf_trace.c bpf: Disable preemption in bpf_event_output 2023-08-20 16:01:36 +08:00
bpf_trace.h
error_report-traces.c
fgraph.c
ftrace.c ftrace: Fix possible warning on checking all pages used in ftrace_process_locs() 2023-08-20 16:01:06 +08:00
ftrace_internal.h
Kconfig tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE 2023-04-19 17:58:15 +08:00
kprobe_event_gen_test.c tracing: Fix wrong return in kprobe_event_gen_test.c 2023-04-19 18:01:11 +08:00
Makefile tracing: Place trace_pid_list logic into abstract functions 2023-04-19 17:51:47 +08:00
pid_list.c tracing: Place trace_pid_list logic into abstract functions 2023-04-19 17:51:47 +08:00
pid_list.h tracing: Place trace_pid_list logic into abstract functions 2023-04-19 17:51:47 +08:00
power-traces.c
preemptirq_delay_test.c
ring_buffer.c ring-buffer: Do not swap cpu_buffer during resize process 2023-08-28 23:26:57 +08:00
ring_buffer_benchmark.c
rpm-traces.c
synth_event_gen_test.c tracing: Fix memory leak in test_gen_synth_cmd() and test_empty_synth_event() 2023-04-19 17:56:24 +08:00
trace.c tracing: Fix memleak due to race between current_tracer and trace 2023-09-05 01:25:05 +08:00
trace.h Revert "tracing: Add "(fault)" name injection to kernel probes" 2023-08-20 16:01:17 +08:00
trace_benchmark.c
trace_benchmark.h
trace_boot.c tracing: Initialize integer variable to prevent garbage return value 2023-04-19 17:50:00 +08:00
trace_branch.c
trace_clock.c
trace_dynevent.c tracing: Free buffers when a used dynamic event is removed 2023-04-19 17:56:52 +08:00
trace_dynevent.h
trace_entries.h
trace_eprobe.c kernel/trace: Fix cleanup logic of enable_trace_eprobe 2023-08-20 15:24:55 +08:00
trace_event_perf.c tracing/perf: Fix double put of trace event when init fails 2023-04-19 17:53:00 +08:00
trace_events.c tracing: Fix warning in trace_buffered_event_disable() 2023-08-20 16:01:22 +08:00
trace_events_filter.c tracing: Add ustring operation to filtering string pointers 2023-04-19 17:45:50 +08:00
trace_events_filter_test.h
trace_events_hist.c tracing: Allow synthetic events to pass around stacktraces 2023-08-20 16:01:17 +08:00
trace_events_inject.c
trace_events_synth.c tracing: Fix trace_event_raw_event_synth() if else statement 2023-08-20 16:01:26 +08:00
trace_events_trigger.c tracing: Fix to check event_mutex is held while accessing trigger list 2023-04-19 17:53:44 +08:00
trace_export.c
trace_functions.c
trace_functions_graph.c tracing: Disable "other" permission bits in the tracefs files 2023-04-19 16:57:10 +08:00
trace_hwlat.c trace/hwlat: Do not start per-cpu thread if it is already running 2023-04-19 18:00:58 +08:00
trace_irqsoff.c tracing: Fix memleak due to race between current_tracer and trace 2023-09-05 01:25:05 +08:00
trace_kdb.c
trace_kprobe.c tracing: Move duplicate code of trace_kprobe/eprobe.c into header 2023-04-19 17:55:06 +08:00
trace_kprobe_selftest.c
trace_kprobe_selftest.h
trace_mmiotrace.c
trace_nop.c
trace_osnoise.c tracing/osnoise: Fix duration type 2023-04-19 17:56:52 +08:00
trace_output.c tracing: Make sure trace_printk() can output as soon as it can be used 2023-04-19 17:59:01 +08:00
trace_output.h
trace_preemptirq.c tracing: hold caller_addr to hardirq_{enable,disable}_ip 2023-04-19 17:53:51 +08:00
trace_printk.c tracing: Disable "other" permission bits in the tracefs files 2023-04-19 16:57:10 +08:00
trace_probe.c Revert "tracing: Add "(fault)" name injection to kernel probes" 2023-08-20 16:01:17 +08:00
trace_probe.h tracing/probes: Add symstr type for dynamic events 2023-08-20 16:01:17 +08:00
trace_probe_kernel.h tracing/probes: Fix to record 0-length data_loc in fetch_store_string*() if fails 2023-08-20 16:01:17 +08:00
trace_probe_tmpl.h tracing/probes: Fix to record 0-length data_loc in fetch_store_string*() if fails 2023-08-20 16:01:17 +08:00
trace_recursion_record.c tracing: Disable "other" permission bits in the tracefs files 2023-04-19 16:57:10 +08:00
trace_sched_switch.c
trace_sched_wakeup.c tracing: Fix memleak due to race between current_tracer and trace 2023-09-05 01:25:05 +08:00
trace_selftest.c
trace_selftest_dynamic.c
trace_seq.c
trace_stack.c tracing: Disable "other" permission bits in the tracefs files 2023-04-19 16:57:10 +08:00
trace_stat.c tracing: Disable "other" permission bits in the tracefs files 2023-04-19 16:57:10 +08:00
trace_stat.h
trace_synth.h tracing: Allow synthetic events to pass around stacktraces 2023-08-20 16:01:17 +08:00
trace_syscalls.c tracing: Make tp_printk work on syscall tracepoints 2023-04-19 17:50:17 +08:00
trace_uprobe.c tracing/probes: Fix to record 0-length data_loc in fetch_store_string*() if fails 2023-08-20 16:01:17 +08:00
tracing_map.c tracing: Fix a kmemleak false positive in tracing_map 2023-04-19 17:43:06 +08:00
tracing_map.h