tracing fixes for v6.16:

- 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
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYKADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCaF/yIRQccm9zdGVkdEBn
 b29kbWlzLm9yZwAKCRAp5XQQmuv6qpoNAP9AuI6SzS+E14UFbA7lEPVtQAgaj6rv
 xURhlmZdsGJ2AQEA3ZTv6Lf3DbnSHzPDOUnK9ItQZE7UHPh4Yed0QrriEAM=
 =hFZ1
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2025-06-28 11:39:24 -07:00
commit ded779017a

View File

@ -1436,13 +1436,6 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,
INIT_LIST_HEAD(&head->list);
item = kmalloc(sizeof(*item), GFP_KERNEL);
if (!item)
goto free_now;
item->filter = filter;
list_add_tail(&item->list, &head->list);
list_for_each_entry(file, &tr->events, list) {
if (file->system != dir)
continue;
@ -1454,6 +1447,13 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,
event_clear_filter(file);
}
item = kmalloc(sizeof(*item), GFP_KERNEL);
if (!item)
goto free_now;
item->filter = filter;
list_add_tail(&item->list, &head->list);
delay_free_filter(head);
return;
free_now: