FAILED: patch "[PATCH] tracing: Fix bad hist from corrupting named_triggers list" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 6f86bdeab633a56d5c6dccf1a2c5989b6a5e323e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025030435-impurity-modular-98f0@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 6f86bdeab633a56d5c6dccf1a2c5989b6a5e323e Mon Sep 17 00:00:00 2001
From: Steven Rostedt <[email protected]>
Date: Thu, 27 Feb 2025 16:39:44 -0500
Subject: [PATCH] tracing: Fix bad hist from corrupting named_triggers list
The following commands causes a crash:
~# cd /sys/kernel/tracing/events/rcu/rcu_callback
~# echo 'hist:name=bad:keys=common_pid:onmax(bogus).save(common_pid)' > trigger
bash: echo: write error: Invalid argument
~# echo 'hist:name=bad:keys=common_pid' > trigger
Because the following occurs:
event_trigger_write() {
trigger_process_regex() {
event_hist_trigger_parse() {
data = event_trigger_alloc(..);
event_trigger_register(.., data) {
cmd_ops->reg(.., data, ..) [hist_register_trigger()] {
data->ops->init() [event_hist_trigger_init()] {
save_named_trigger(name, data) {
list_add(&data->named_list, &named_triggers);
}
}
}
}
ret = create_actions(); (return -EINVAL)
if (ret)
goto out_unreg;
[..]
ret = hist_trigger_enable(data, ...) {
list_add_tail_rcu(&data->list, &file->triggers); <<<---- SKIPPED!!! (this is important!)
[..]
out_unreg:
event_hist_unregister(.., data) {
cmd_ops->unreg(.., data, ..) [hist_unregister_trigger()] {
list_for_each_entry(iter, &file->triggers, list) {
if (!hist_trigger_match(data, iter, named_data, false)) <- never matches
continue;
[..]
test = iter;
}
if (test && test->ops->free) <<<-- test is NULL
test->ops->free(test) [event_hist_trigger_free()] {
[..]
if (data->name)
del_named_trigger(data) {
list_del(&data->named_list); <<<<-- NEVER gets removed!
}
}
}
}
[..]
kfree(data); <<<-- frees item but it is still on listThe next time a hist with name is registered, it causes an u-a-f bug and the kernel can crash.
Move the code around such that if event_trigger_register() succeeds, the next thing called is hist_trigger_enable() which adds it to the list.
A bunch of actions is called if get_named_trigger_data() returns false. But that doesn't need to be called after event_trigger_register(), so it can be moved up, allowing event_trigger_register() to be called just before hist_trigger_enable() keeping them together and allowing the file->triggers to be properly populated.
kernel/trace/trace_events_hist.c +17 -17
@@ -6724,27 +6724,27 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops,if (existing_hist_update_only (glob, trigger_data, file)) goto out_free; +if (!get_named_trigger_data (trigger_data)) { + + ret =create_actions (hist_data); +if (ret) + goto out_free; + +if (has_hist_vars (hist_data) || hist_data->n_var_refs) { + ret =save_hist_vars (hist_data); +if (ret) + goto out_free; + } + + ret =tracing_map_init (hist_data->map); +if (ret) + goto out_free; + } + ret =event_trigger_register (cmd_ops, file, glob, trigger_data);if (ret <0 ) goto out_free; -if (get_named_trigger_data (trigger_data)) - goto enable; - - ret =create_actions (hist_data); -if (ret) - goto out_unreg; - -if (has_hist_vars (hist_data) || hist_data->n_var_refs) { - ret =save_hist_vars (hist_data); -if (ret) - goto out_unreg; - } - - ret =tracing_map_init (hist_data->map); -if (ret) - goto out_unreg; -enable: ret =hist_trigger_enable (trigger_data, file);if (ret) goto out_unreg;