[PATCH] tracing: Fix filter logic error

Edward Adam Davis posted 1 patch 3 months, 2 weeks ago
There is a newer version of this series
kernel/trace/trace_events_filter.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
[PATCH] tracing: Fix filter logic error
Posted by Edward Adam Davis 3 months, 2 weeks ago
If the processing of the tr->events loop fails, the filter that has been
added to filter_head will be released twice in free_filter_list(&head->rcu)
and __free_filter(filter).

After adding the filter of tr->events, add the filter to the filter_head
process to avoid triggering uaf.

Fixes: a9d0aab5eb33 ("tracing: Fix regression of filter waiting a long time on RCU synchronization")
Reported-by: syzbot+daba72c4af9915e9c894@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=daba72c4af9915e9c894
Tested-by: syzbot+daba72c4af9915e9c894@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
 kernel/trace/trace_events_filter.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 08141f105c95..3885aadc434d 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -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:
-- 
2.43.0
Re: [PATCH] tracing: Fix filter logic error
Posted by Steven Rostedt 3 months, 2 weeks ago
On Tue, 24 Jun 2025 14:38:46 +0800
Edward Adam Davis <eadavis@qq.com> wrote:

> If the processing of the tr->events loop fails, the filter that has been
> added to filter_head will be released twice in free_filter_list(&head->rcu)
> and __free_filter(filter).
> 
> After adding the filter of tr->events, add the filter to the filter_head
> process to avoid triggering uaf.

Ah that was the kmalloc that failed.

Thanks,

-- Steve
Re: [PATCH] tracing: Fix filter logic error
Posted by Masami Hiramatsu (Google) 3 months, 2 weeks ago
On Tue, 24 Jun 2025 14:38:46 +0800
Edward Adam Davis <eadavis@qq.com> wrote:

> If the processing of the tr->events loop fails, the filter that has been
> added to filter_head will be released twice in free_filter_list(&head->rcu)
> and __free_filter(filter).
> 
> After adding the filter of tr->events, add the filter to the filter_head
> process to avoid triggering uaf.

Looks good to me.

Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>

Thank you,

> 
> Fixes: a9d0aab5eb33 ("tracing: Fix regression of filter waiting a long time on RCU synchronization")
> Reported-by: syzbot+daba72c4af9915e9c894@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=daba72c4af9915e9c894
> Tested-by: syzbot+daba72c4af9915e9c894@syzkaller.appspotmail.com
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
> ---
>  kernel/trace/trace_events_filter.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
> index 08141f105c95..3885aadc434d 100644
> --- a/kernel/trace/trace_events_filter.c
> +++ b/kernel/trace/trace_events_filter.c
> @@ -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:
> -- 
> 2.43.0
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>