Skip to content

Commit ded7790

Browse files
committed
Merge tag 'trace-v6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fix from Steven Rostedt: - Fix possible UAF on error path in filter_free_subsystem_filters() When freeing a subsystem filter, the filter for the subsystem is passed in to be freed and all the events within the subsystem will have their filter freed too. In order to free without waiting for RCU synchronization, list items are allocated to hold what is going to be freed to free it via a call_rcu(). If the allocation of these items fails, it will call the synchronization directly and free after that (causing a bit of delay for the user). The subsystem filter is first added to this list and then the filters for all the events under the subsystem. The bug is if one of the allocations of the list items for the event filters fail to allocate, it jumps to the "free_now" label which will free the subsystem filter, then all the items on the allocated list, and then the event filters that were not added to the list yet. But because the subsystem filter was added first, it gets freed twice. The solution is to add the subsystem filter after the events, and then if any of the allocations fail it will not try to free any of them twice * tag 'trace-v6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing: Fix filter logic error
2 parents 3a3de75 + 6921d1e commit ded7790

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

kernel/trace/trace_events_filter.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,13 +1436,6 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,
14361436

14371437
INIT_LIST_HEAD(&head->list);
14381438

1439-
item = kmalloc(sizeof(*item), GFP_KERNEL);
1440-
if (!item)
1441-
goto free_now;
1442-
1443-
item->filter = filter;
1444-
list_add_tail(&item->list, &head->list);
1445-
14461439
list_for_each_entry(file, &tr->events, list) {
14471440
if (file->system != dir)
14481441
continue;
@@ -1454,6 +1447,13 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,
14541447
event_clear_filter(file);
14551448
}
14561449

1450+
item = kmalloc(sizeof(*item), GFP_KERNEL);
1451+
if (!item)
1452+
goto free_now;
1453+
1454+
item->filter = filter;
1455+
list_add_tail(&item->list, &head->list);
1456+
14571457
delay_free_filter(head);
14581458
return;
14591459
free_now:

0 commit comments

Comments
 (0)