ftrace: Fix use-after-free for dynamic ftrace_ops
[platform/kernel/linux-starfive.git] / kernel / trace / ftrace.c
index fbf2543..7dc0236 100644 (file)
@@ -3028,18 +3028,8 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
                command |= FTRACE_UPDATE_TRACE_FUNC;
        }
 
-       if (!command || !ftrace_enabled) {
-               /*
-                * If these are dynamic or per_cpu ops, they still
-                * need their data freed. Since, function tracing is
-                * not currently active, we can just free them
-                * without synchronizing all CPUs.
-                */
-               if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
-                       goto free_ops;
-
-               return 0;
-       }
+       if (!command || !ftrace_enabled)
+               goto out;
 
        /*
         * If the ops uses a trampoline, then it needs to be
@@ -3076,6 +3066,7 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
        removed_ops = NULL;
        ops->flags &= ~FTRACE_OPS_FL_REMOVING;
 
+out:
        /*
         * Dynamic ops may be freed, we must make sure that all
         * callers are done before leaving this function.
@@ -3103,7 +3094,6 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
                if (IS_ENABLED(CONFIG_PREEMPTION))
                        synchronize_rcu_tasks();
 
- free_ops:
                ftrace_trampoline_free(ops);
        }