--- /dev/null
+From stable+bounces-227966-greg=kroah.com@vger.kernel.org Mon Mar 23 14:01:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Mar 2026 08:52:55 -0400
+Subject: tracing: Fix trace_marker copy link list updates
+To: stable@vger.kernel.org
+Cc: Steven Rostedt <rostedt@goodmis.org>, Masami Hiramatsu <mhiramat@kernel.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260323125255.1649344-1-sashal@kernel.org>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 07183aac4a6828e474f00b37c9d795d0d99e18a7 ]
+
+When the "copy_trace_marker" option is enabled for an instance, anything
+written into /sys/kernel/tracing/trace_marker is also copied into that
+instances buffer. When the option is set, that instance's trace_array
+descriptor is added to the marker_copies link list. This list is protected
+by RCU, as all iterations uses an RCU protected list traversal.
+
+When the instance is deleted, all the flags that were enabled are cleared.
+This also clears the copy_trace_marker flag and removes the trace_array
+descriptor from the list.
+
+The issue is after the flags are called, a direct call to
+update_marker_trace() is performed to clear the flag. This function
+returns true if the state of the flag changed and false otherwise. If it
+returns true here, synchronize_rcu() is called to make sure all readers
+see that its removed from the list.
+
+But since the flag was already cleared, the state does not change and the
+synchronization is never called, leaving a possible UAF bug.
+
+Move the clearing of all flags below the updating of the copy_trace_marker
+option which then makes sure the synchronization is performed.
+
+Also use the flag for checking the state in update_marker_trace() instead
+of looking at if the list is empty.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://patch.msgid.link/20260318185512.1b6c7db4@gandalf.local.home
+Fixes: 7b382efd5e8a ("tracing: Allow the top level trace_marker to write into another instances")
+Reported-by: Sasha Levin <sashal@kernel.org>
+Closes: https://lore.kernel.org/all/20260225133122.237275-1-sashal@kernel.org/
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -569,7 +569,7 @@ static bool update_marker_trace(struct t
+ lockdep_assert_held(&event_mutex);
+
+ if (enabled) {
+- if (!list_empty(&tr->marker_list))
++ if (tr->trace_flags & TRACE_ITER_COPY_MARKER)
+ return false;
+
+ list_add_rcu(&tr->marker_list, &marker_copies);
+@@ -577,10 +577,10 @@ static bool update_marker_trace(struct t
+ return true;
+ }
+
+- if (list_empty(&tr->marker_list))
++ if (!(tr->trace_flags & TRACE_ITER_COPY_MARKER))
+ return false;
+
+- list_del_init(&tr->marker_list);
++ list_del_rcu(&tr->marker_list);
+ tr->trace_flags &= ~TRACE_ITER_COPY_MARKER;
+ return true;
+ }
+@@ -10232,18 +10232,19 @@ static int __remove_instance(struct trac
+
+ list_del(&tr->list);
+
+- /* Disable all the flags that were enabled coming in */
+- for (i = 0; i < TRACE_FLAGS_MAX_SIZE; i++) {
+- if ((1 << i) & ZEROED_TRACE_FLAGS)
+- set_tracer_flag(tr, 1 << i, 0);
+- }
+-
+ if (printk_trace == tr)
+ update_printk_trace(&global_trace);
+
++ /* Must be done before disabling all the flags */
+ if (update_marker_trace(tr, 0))
+ synchronize_rcu();
+
++ /* Disable all the flags that were enabled coming in */
++ for (i = 0; i < TRACE_FLAGS_MAX_SIZE; i++) {
++ if ((1 << i) & ZEROED_TRACE_FLAGS)
++ set_tracer_flag(tr, 1 << i, 0);
++ }
++
+ tracing_set_nop(tr);
+ clear_ftrace_function_probes(tr);
+ event_trace_del_tracer(tr);