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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'probes-fixes-v6.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull probes fixes from Masami Hiramatsu:

- fprobe: Fix RCU warning message in list traversal

fprobe_module_callback() using hlist_for_each_entry_rcu() traverse
the fprobe list but it locks fprobe_mutex() instead of rcu lock
because it is enough. So add lockdep_is_held() to avoid warning.

- tracing: eprobe: Add missing trace_probe_log_clear for eprobe

__trace_eprobe_create() uses trace_probe_log but forgot to clear it
at exit. Add trace_probe_log_clear() calls.

- tracing: probes: Fix possible race in trace_probe_log APIs

trace_probe_log APIs are used in probe event (dynamic_events,
kprobe_events and uprobe_events) creation. Only dynamic_events uses
the dyn_event_ops_mutex mutex to serialize it. This makes kprobe and
uprobe events to lock the same mutex to serialize its creation to
avoid race in trace_probe_log APIs.

* tag 'probes-fixes-v6.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
tracing: probes: Fix a possible race in trace_probe_log APIs
tracing: add missing trace_probe_log_clear for eprobes
tracing: fprobe: Fix RCU warning message in list traversal

+32 -4
+2 -1
kernel/trace/fprobe.c
··· 454 454 struct fprobe_hlist_node *node; 455 455 int ret = 0; 456 456 457 - hlist_for_each_entry_rcu(node, head, hlist) { 457 + hlist_for_each_entry_rcu(node, head, hlist, 458 + lockdep_is_held(&fprobe_mutex)) { 458 459 if (!within_module(node->addr, mod)) 459 460 continue; 460 461 if (delete_fprobe_node(node))
+15 -1
kernel/trace/trace_dynevent.c
··· 16 16 #include "trace_output.h" /* for trace_event_sem */ 17 17 #include "trace_dynevent.h" 18 18 19 - static DEFINE_MUTEX(dyn_event_ops_mutex); 19 + DEFINE_MUTEX(dyn_event_ops_mutex); 20 20 static LIST_HEAD(dyn_event_ops_list); 21 21 22 22 bool trace_event_dyn_try_get_ref(struct trace_event_call *dyn_call) ··· 113 113 } 114 114 tracing_reset_all_online_cpus(); 115 115 mutex_unlock(&event_mutex); 116 + return ret; 117 + } 118 + 119 + /* 120 + * Locked version of event creation. The event creation must be protected by 121 + * dyn_event_ops_mutex because of protecting trace_probe_log. 122 + */ 123 + int dyn_event_create(const char *raw_command, struct dyn_event_operations *type) 124 + { 125 + int ret; 126 + 127 + mutex_lock(&dyn_event_ops_mutex); 128 + ret = type->create(raw_command); 129 + mutex_unlock(&dyn_event_ops_mutex); 116 130 return ret; 117 131 } 118 132
+1
kernel/trace/trace_dynevent.h
··· 100 100 void dyn_event_seq_stop(struct seq_file *m, void *v); 101 101 int dyn_events_release_all(struct dyn_event_operations *type); 102 102 int dyn_event_release(const char *raw_command, struct dyn_event_operations *type); 103 + int dyn_event_create(const char *raw_command, struct dyn_event_operations *type); 103 104 104 105 /* 105 106 * for_each_dyn_event - iterate over the dyn_event list
+3
kernel/trace/trace_eprobe.c
··· 969 969 goto error; 970 970 } 971 971 } 972 + trace_probe_log_clear(); 972 973 return ret; 974 + 973 975 parse_error: 974 976 ret = -EINVAL; 975 977 error: 978 + trace_probe_log_clear(); 976 979 trace_event_probe_cleanup(ep); 977 980 return ret; 978 981 }
+1 -1
kernel/trace/trace_kprobe.c
··· 1089 1089 if (raw_command[0] == '-') 1090 1090 return dyn_event_release(raw_command, &trace_kprobe_ops); 1091 1091 1092 - ret = trace_kprobe_create(raw_command); 1092 + ret = dyn_event_create(raw_command, &trace_kprobe_ops); 1093 1093 return ret == -ECANCELED ? -EINVAL : ret; 1094 1094 } 1095 1095
+9
kernel/trace/trace_probe.c
··· 154 154 } 155 155 156 156 static struct trace_probe_log trace_probe_log; 157 + extern struct mutex dyn_event_ops_mutex; 157 158 158 159 void trace_probe_log_init(const char *subsystem, int argc, const char **argv) 159 160 { 161 + lockdep_assert_held(&dyn_event_ops_mutex); 162 + 160 163 trace_probe_log.subsystem = subsystem; 161 164 trace_probe_log.argc = argc; 162 165 trace_probe_log.argv = argv; ··· 168 165 169 166 void trace_probe_log_clear(void) 170 167 { 168 + lockdep_assert_held(&dyn_event_ops_mutex); 169 + 171 170 memset(&trace_probe_log, 0, sizeof(trace_probe_log)); 172 171 } 173 172 174 173 void trace_probe_log_set_index(int index) 175 174 { 175 + lockdep_assert_held(&dyn_event_ops_mutex); 176 + 176 177 trace_probe_log.index = index; 177 178 } 178 179 ··· 184 177 { 185 178 char *command, *p; 186 179 int i, len = 0, pos = 0; 180 + 181 + lockdep_assert_held(&dyn_event_ops_mutex); 187 182 188 183 if (!trace_probe_log.argv) 189 184 return;
+1 -1
kernel/trace/trace_uprobe.c
··· 741 741 if (raw_command[0] == '-') 742 742 return dyn_event_release(raw_command, &trace_uprobe_ops); 743 743 744 - ret = trace_uprobe_create(raw_command); 744 + ret = dyn_event_create(raw_command, &trace_uprobe_ops); 745 745 return ret == -ECANCELED ? -EINVAL : ret; 746 746 } 747 747