]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tracing: Fix race between update_event_fields and, event_define_fields
authorMichael Wu <michael@allwinnertech.com>
Mon, 10 Aug 2026 06:32:30 +0000 (14:32 +0800)
committerSteven Rostedt <rostedt@goodmis.org>
Thu, 13 Aug 2026 19:38:25 +0000 (15:38 -0400)
The following sequence may leads race between event_define_fields()
and update_event_fields():

 CPU0 (loads module A)                      CPU1 (loads module B)
 ===============================            ===============================
 load_module(A)                             load_module(B)
   notifier_call_chain                        notifier_call_chain
     trace_module_notify                        trace_module_notify
       mutex_lock(&event_mutex)                   trace_event_update_all()
         trace_module_add_events(A)                 down_write(&trace_event_sem)
            __register_event(call_A)
              __add_event_to_tracers(call_A)
                event_define_fields(call_A)
                  for each f:                         list_for_each_entry(field,
                    list_add(&f->link,                                    &class->fields, link)
                             &class->fields)            field = class->fields->next;

Where access to the class->fields is not protected by the event_mutex in
trace_event_update_all().

This produces the following panic:
   Unable to handle kernel access ... at virtual address 0000000000000018
   pc : update_event_fields+0xf8/0x368
   Call trace:
    update_event_fields+0xf8/0x368
    trace_event_update_all+0x7c/0x2b4
    trace_module_notify+0x4c/0x1dc
    notifier_call_chain+0x84/0x168
    blocking_notifier_call_chain_robust+0x64/0xd4
    load_module+0x10c8/0x123c
    __arm64_sys_finit_module+0x230/0x31c

Fix by taking event_mutex in trace_event_update_all() before
trace_event_sem.

Cc: stable@vger.kernel.org
Fixes: b3bc8547d3be ("tracing: Have TRACE_DEFINE_ENUM affect trace event types as well")
Link: https://patch.msgid.link/2e5730d2-c631-da41-3a3a-ae35bb4895f3@allwinnertech.com
Signed-off-by: Michael Wu <michael@allwinnertech.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
kernel/trace/trace_events.c

index 032f741ba6162c91efea94604957fa26aaed28c2..3650d84d4f16c268887657faaf1d84242408c6cd 100644 (file)
@@ -3566,6 +3566,7 @@ void trace_event_update_all(struct trace_eval_map **map, int len)
        int last_i;
        int i;
 
+       mutex_lock(&event_mutex);
        down_write(&trace_event_sem);
        list_for_each_entry_safe(call, p, &ftrace_events, list) {
                /* events are usually grouped together with systems */
@@ -3604,6 +3605,7 @@ void trace_event_update_all(struct trace_eval_map **map, int len)
                cond_resched();
        }
        up_write(&trace_event_sem);
+       mutex_unlock(&event_mutex);
 }
 
 static bool event_in_systems(struct trace_event_call *call,