Skip to contentSkip to conversation

ftrace: UAF in ftrace_regex_open() on a removed tracing instance

DISCUSSION Breno Leitao 2 participants 7 messages Aug 28

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

I am seeing some UAF KASAN issue on ftrace in Meta prod, and I think I got a reproducer that works ok.

 BUG: KASAN: slab-use-after-free in ftrace_regex_open+0x50/0x770
  Read of size 8 at addr ffff00097627f418 by task stress-ng-fanot/1811644

  CPU: 22 UID: 0 PID: 1811644 Comm: stress-ng-fanot Kdump: loaded Tainted: G            E       7.2.0-next-20260827upstream #2
  PREEMPT(full)
  Call trace:
   show_stack+0x20/0x38 (C)
   __dump_stack+0x28/0x38
   dump_stack_lvl+0x74/0xa8
   print_report+0xd8/0x250
   kasan_report+0x98/0xf8
   __asan_report_load8_noabort+0x20/0x30
   ftrace_regex_open+0x50/0x770
   ftrace_filter_open+0x44/0x58
   do_dentry_open+0x308/0xd20
   vfs_open+0x44/0x280
   dentry_open_nonotify+0x68/0xc0
   fanotify_read+0x5c0/0x1d78
   vfs_read+0x198/0x6f0
   ksys_read+0xbc/0x168
   __arm64_sys_read+0x88/0xa8
   invoke_syscall+0x74/0x188
   do_el0_svc+0x108/0x190
   el0_svc+0x64/0x260
   el0t_64_sync_handler+0x68/0xe0
   el0t_64_sync+0x198/0x1a0

  Allocated by task 1808767:
   kasan_save_track+0x30/0x68
   kasan_save_alloc_info+0x40/0x50
   __kasan_kmalloc+0x84/0xa0
   __kmalloc_cache_noprof+0x2b4/0x588
   ftrace_allocate_ftrace_ops+0x84/0x148
   trace_array_create_systems+0x470/0x13e8
   instance_mkdir+0xcc/0x118
   tracefs_syscall_mkdir+0xa0/0xf0
   vfs_mkdir+0x2a0/0x3d8
   filename_mkdirat+0x1c4/0x368
   __arm64_sys_mkdirat+0xa4/0x198
   invoke_syscall+0x74/0x188
   do_el0_svc+0x108/0x190
   el0_svc+0x64/0x260
   el0t_64_sync_handler+0x68/0xe0
   el0t_64_sync+0x198/0x1a0

  Freed by task 1812034:
   kasan_save_track+0x30/0x68
   kasan_save_free_info+0x54/0x70
   __kasan_slab_free+0x58/0x88
   kfree+0x194/0x6b0
   ftrace_destroy_function_files+0x5c/0x90
   __remove_instance+0x424/0xa68
   instance_rmdir+0xb8/0xf8
   tracefs_syscall_rmdir+0x84/0xf8
   vfs_rmdir+0x18c/0x458
   filename_rmdir+0x1a0/0x310
   __arm64_sys_unlinkat+0xb0/0x1c0
   invoke_syscall+0x74/0x188
   do_el0_svc+0x108/0x190
   el0_svc+0x64/0x260
   el0t_64_sync_handler+0x68/0xe0
   el0t_64_sync+0x198/0x1a0

  The buggy address belongs to the object at ffff00097627f400
   which belongs to the cache kmalloc-512 of size 512
  The buggy address is located 24 bytes inside of
   freed 512-byte region [ffff00097627f400, ffff00097627f600)

  The buggy address belongs to the physical page:
  page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9f6278
  head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
  flags: 0x5ffff0000000040(head|node=0|zone=2|lastcpupid=0x1ffff)
  page_type: f5(slab)
  raw: 05ffff0000000040 ffff000080008c80 dead000000000100 dead000000000122
  raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
  head: 05ffff0000000040 ffff000080008c80 dead000000000100 dead000000000122
  head: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
  head: 05ffff0000000003 fffffdffe5d89e01 00000000ffffffff 00000000ffffffff
  head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
  page dumped because: kasan: bad access detected

  Memory state around the buggy address:
   ffff00097627f300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
   ffff00097627f380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  >ffff00097627f400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                              ^
   ffff00097627f480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   ffff00097627f500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
  ==================================================================

Reproducer
----------

Needs root and CONFIG_KASAN=y, CONFIG_FANOTIFY=y, CONFIG_DYNAMIC_FTRACE=y. It is deterministic and fires on the first read():

It seems it was introduced by 591dffdade9f ("ftrace: Allow for function tracing instance to filter functions") in v3.15, so all stable trees are affected. A fix is attached.

Thanks,
Breno

---
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/fanotify.h>
#include <sys/stat.h>

#define TRACEFS "/sys/kernel/tracing"
#define INSTANCE TRACEFS "/instances/uaf"
#define TARGET INSTANCE "/set_ftrace_filter"

int main(void)

{
	char buf[4096];
	int fan, fd;

	fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY);
	if (fan < 0)
		return perror("fanotify_init"), 1;
	if (fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_OPEN,
			  AT_FDCWD, TRACEFS) < 0)
		return perror("fanotify_mark"), 1;

	rmdir(INSTANCE);
	if (mkdir(INSTANCE, 0755) < 0)
		return perror("mkdir"), 1;

	/* Queues an event; fanotify does path_get() on the file. */
	fd = open(TARGET, O_RDONLY);
	if (fd < 0)
		return perror(TARGET), 1;
	close(fd);

	/* Frees tr->ops while fanotify still pins the path. */
	if (rmdir(INSTANCE) < 0)
		return perror("rmdir"), 1;

	/* create_fd() -> dentry_open_nonotify() -> ftrace_filter_open(). */
	if (read(fan, buf, sizeof(buf)) < 0)
		perror("read");

	return 0;
}
maintainer
#1 lore raw
Quoted 10 lines · On Fri, 28 Aug 2026 06:38:17 -0700 Breno Leitao <[email protected]> wrote:

I am seeing some UAF KASAN issue on ftrace in Meta prod, and I think I got a reproducer that works ok.

 BUG: KASAN: slab-use-after-free in ftrace_regex_open+0x50/0x770
  Read of size 8 at addr ffff00097627f418 by task stress-ng-fanot/1811644

#define TRACEFS "/sys/kernel/tracing"
#define INSTANCE TRACEFS "/instances/uaf"
#define TARGET INSTANCE "/set_ftrace_filter"

Ugg, this is similar to the bug I just fixed[1]. But this one will not be so trivial to solve. As the trace_array in question owns the ftrace_ops that is used to register the set_ftrace_filter file. Upping the reference to the trace_array will require some thought.

Let me look deeper at it.

-- Steve

[1] https://lore.kernel.org/all/[email protected]/

#2 lore raw
Quoted 14 lines · Steven Rostedt
Quoted 10 lines · On Fri, 28 Aug 2026 06:38:17 -0700 Breno Leitao <[email protected]> wrote:

I am seeing some UAF KASAN issue on ftrace in Meta prod, and I think I got a reproducer that works ok.

 BUG: KASAN: slab-use-after-free in ftrace_regex_open+0x50/0x770
  Read of size 8 at addr ffff00097627f418 by task stress-ng-fanot/1811644

#define TRACEFS "/sys/kernel/tracing"
#define INSTANCE TRACEFS "/instances/uaf"
#define TARGET INSTANCE "/set_ftrace_filter"

Quoted 6 lines

Ugg, this is similar to the bug I just fixed[1]. But this one will not be so trivial to solve. As the trace_array in question owns the ftrace_ops that is used to register the set_ftrace_filter file. Upping the reference to the trace_array will require some thought.

Let me look deeper at it.

My LLM came up with something like the following, and it doesn't reproduce the problem anymore. Very similar to your code above:

kernel/trace/ftrace.c +30 -11
index f9d80c7bd9f16..37845399fe5cf 100644
@@ -4788,22 +4788,37 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
 static int
 ftrace_filter_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
+	int ret;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops,
-			FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
-			inode, file);
+	/* Checks for tracefs lockdown, and that the instance is still alive */
+	ret = tracing_check_open_get_tr(tr);
+	if (ret)
+		return ret;
+
+	ret = ftrace_regex_open(tr->ops,
+				FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+				inode, file);
+	/* ftrace_regex_open() holds its own reference on success */
+	trace_array_put(tr);
+	return ret;
 }
 
 static int
 ftrace_notrace_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
+	int ret;
+
+	/* Checks for tracefs lockdown, and that the instance is still alive */
+	ret = tracing_check_open_get_tr(tr);
+	if (ret)
+		return ret;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
-				 inode, file);
+	ret = ftrace_regex_open(tr->ops, FTRACE_ITER_NOTRACE, inode, file);
+	/* ftrace_regex_open() holds its own reference on success */
+	trace_array_put(tr);
+	return ret;
 }
 
 /* Type for quick search ftrace basic regexes (globs) from filter_parse_regex */
@@ -7496,11 +7511,15 @@ void ftrace_create_filter_files(struct ftrace_ops *ops,
 				struct dentry *parent)
 {
 
+	/*
+	 * Pass the trace array and not @ops, as @ops is freed when the
+	 * instance is removed, but the trace array can still be validated.
+	 */
 	trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_filter_fops);
+			  ops->private, &ftrace_filter_fops);
 
 	trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_notrace_fops);
+			  ops->private, &ftrace_notrace_fops);
 }
 
 /*
maintainer
#3 lore raw
Quoted 3 lines · On Fri, 28 Aug 2026 08:59:39 -0700 Breno Leitao <[email protected]> wrote:

My LLM came up with something like the following, and it doesn't reproduce the problem anymore. Very similar to your code above:

I know the solution but there's subtle things I want to make sure that works.

Quoted 53 lines
kernel/trace/ftrace.c +24 -9
index f9d80c7bd9f16..37845399fe5cf 100644
@@ -4788,22 +4788,37 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
 static int
 ftrace_filter_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
+	int ret;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops,
-			FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
-			inode, file);
+	/* Checks for tracefs lockdown, and that the instance is still alive */
+	ret = tracing_check_open_get_tr(tr);
+	if (ret)
+		return ret;
+
+	ret = ftrace_regex_open(tr->ops,
+				FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+				inode, file);
+	/* ftrace_regex_open() holds its own reference on success */
+	trace_array_put(tr);
+	return ret;
 }
 
 static int
 ftrace_notrace_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
+	int ret;
+
+	/* Checks for tracefs lockdown, and that the instance is still alive */
+	ret = tracing_check_open_get_tr(tr);
+	if (ret)
+		return ret;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
-				 inode, file);
+	ret = ftrace_regex_open(tr->ops, FTRACE_ITER_NOTRACE, inode, file);
+	/* ftrace_regex_open() holds its own reference on success */
+	trace_array_put(tr);
+	return ret;
 }
 
 /* Type for quick search ftrace basic regexes (globs) from filter_parse_regex */

kernel/trace/ftrace.c void ftrace_create_filter_files(struct ftrace_ops *ops, · line 7517

Quoted 7 lines
kernel/trace/ftrace.c +4 -0
@@ -7496,11 +7511,15 @@ void ftrace_create_filter_files(struct ftrace_ops *ops,
 				struct dentry *parent)
 {
 
+	/*
+	 * Pass the trace array and not @ops, as @ops is freed when the
+	 * instance is removed, but the trace array can still be validated.
+	 */

I hate these comments. It's really pointless to state this. It's a "no shit" comment ;-)

kernel/trace/ftrace.c void ftrace_create_filter_files(struct ftrace_ops *ops, · line 7519

Quoted 3 lines
kernel/trace/ftrace.c +1 -1
 	trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_filter_fops);
+			  ops->private, &ftrace_filter_fops);

But this also assumes that ops->private is always a trace_array. Which may someday change and we will get a hidden bug if it does.

-- Steve

Quoted 7 lines
kernel/trace/ftrace.c +1 -1
 	trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_notrace_fops);
+			  ops->private, &ftrace_notrace_fops);
 }
 
 /*
maintainer
#4 lore raw
Quoted 8 lines · On Fri, 28 Aug 2026 12:34:52 -0400 Steven Rostedt <[email protected]> wrote:

Review

Quoted 3 lines
(quoted diff) +1 -1
 	trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_filter_fops);
+			  ops->private, &ftrace_filter_fops);  

But this also assumes that ops->private is always a trace_array. Which may someday change and we will get a hidden bug if it does.

This is the exact reason I want to look deeper at it.

Something like this is more robust:

kernel/trace/ftrace.c +40 -13
index f9d80c7bd9f1..a417ad0f3f24 100644
@@ -4786,24 +4786,48 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
 }
 
 static int
-ftrace_filter_open(struct inode *inode, struct file *file)
+__ftrace_regex_open(struct trace_array *tr, int flag,
+		    struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct ftrace_ops *ops;
+	int ret;
+
+	if (trace_array_get(tr) < 0)
+		return -ENODEV;
+
+	ret = -EINVAL;
+	ops = tr->ops;
+	if (!ops)
+		goto fail;
 
 	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops,
-			FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
-			inode, file);
+	ret = ftrace_regex_open(ops, flag, inode, file);
+	if (ret < 0)
+		goto fail;
+
+	return ret;
+ fail:
+	trace_array_put(tr);
+	return ret;
+}
+
+static int
+ftrace_filter_open(struct inode *inode, struct file *file)
+{
+	struct trace_array *tr = inode->i_private;
+
+	return __ftrace_regex_open(tr,
+				   FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+				   inode, file);
 }
 
 static int
 ftrace_notrace_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
-				 inode, file);
+	return __ftrace_regex_open(tr, FTRACE_ITER_NOTRACE,
+				  inode, file);
 }
 
 /* Type for quick search ftrace basic regexes (globs) from filter_parse_regex */
@@ -7492,15 +7516,15 @@ static const struct file_operations ftrace_graph_notrace_fops = {
 };
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
 				struct dentry *parent)
 {
 
 	trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_filter_fops);
+			  tr, &ftrace_filter_fops);
 
 	trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_notrace_fops);
+			  tr, &ftrace_notrace_fops);
 }
 
 /*
@@ -7525,6 +7549,7 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops)
 
 static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
 {
+	struct trace_array *tr;
 
 	trace_create_file("available_filter_functions", TRACE_MODE_READ,
 			d_tracer, NULL, &ftrace_avail_fops);
@@ -7538,7 +7563,9 @@ static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
 	trace_create_file("touched_functions", TRACE_MODE_READ,
 			d_tracer, NULL, &ftrace_touched_fops);
 
-	ftrace_create_filter_files(&global_ops, d_tracer);
+	tr = global_ops.private;
+	if (!WARN_ON(tr == NULL))
+		ftrace_create_filter_files(tr, d_tracer);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	trace_create_file("set_graph_function", TRACE_MODE_WRITE, d_tracer,
kernel/trace/trace.h +3 -2
index 74a7a50d1e78..3c111ca88e32 100644
@@ -1340,7 +1340,7 @@ extern void clear_ftrace_function_probes(struct trace_array *tr);
 int register_ftrace_command(struct ftrace_func_command *cmd);
 int unregister_ftrace_command(struct ftrace_func_command *cmd);
 
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
 				struct dentry *parent);
 void ftrace_destroy_filter_files(struct ftrace_ops *ops);
 
@@ -1363,11 +1363,12 @@ static inline void clear_ftrace_function_probes(struct trace_array *tr)
 {
 }
 
+static inline void ftrace_create_filter_files(struct trace_array *tr,
+					      struct dentry *parent) { }
 /*
  * The ops parameter passed in is usually undefined.
  * This must be a macro.
  */
-#define ftrace_create_filter_files(ops, parent) do { } while (0)
 #define ftrace_destroy_filter_files(ops) do { } while (0)
 #endif /* CONFIG_FUNCTION_TRACER && CONFIG_DYNAMIC_FTRACE */
 
kernel/trace/trace_functions.c +1 -1
index cd37f2013758..c879d43a5fbb 100644
@@ -101,7 +101,7 @@ int ftrace_create_function_files(struct trace_array *tr,
 		return ret;
 	}
 
-	ftrace_create_filter_files(tr->ops, parent);
+	ftrace_create_filter_files(tr, parent);
 
 	return 0;
 }

-- Steve

maintainer
#5 lore raw
In reply to Breno Leitao
Quoted 9 lines · On Fri, 28 Aug 2026 08:59:39 -0700 Breno Leitao <[email protected]> wrote:

ftrace_filter_open(struct inode *inode, struct file *file) {

kernel/trace/ftrace.c +2 -4
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
+	int ret;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops,
-			FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,

kernel/trace/ftrace.c ftrace_regex_open(struct ftrace_ops *ops, int flag, · line 4802

Quoted 10 lines
kernel/trace/ftrace.c +9 -1
-			inode, file);
+	/* Checks for tracefs lockdown, and that the instance is still alive */
+	ret = tracing_check_open_get_tr(tr);
+	if (ret)
+		return ret;
+
+	ret = ftrace_regex_open(tr->ops,
+				FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+				inode, file);
+	/* ftrace_regex_open() holds its own reference on success */

Hmm, I just noticed this part (from reviewing my own code first, and then looking at what your AI did).

I guess the issue is that the ops may be freed before you get access to the trace array. Anyway more needs to be changed. I may remove the extra reference. No need to do it twice. Also since trace_stack may have the issue too.

-- Steve

Quoted 3 lines
kernel/trace/ftrace.c +2 -0
+	trace_array_put(tr);
+	return ret;
 }
maintainer
#6 lore raw
Quoted 4 lines · On Fri, 28 Aug 2026 14:04:11 -0400 Steven Rostedt <[email protected]> wrote:

I guess the issue is that the ops may be freed before you get access to the trace array. Anyway more needs to be changed. I may remove the extra reference. No need to do it twice. Also since trace_stack may have the issue too.

Something more like this:

include/linux/ftrace.h +3 -2
index 02bc5027523a..bd76a16a63af 100644
@@ -866,8 +866,9 @@ unsigned long ftrace_get_addr_new(struct dyn_ftrace *rec);
 unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec);
 
 extern ftrace_func_t ftrace_trace_function;
+struct trace_array;
 
-int ftrace_regex_open(struct ftrace_ops *ops, int flag,
+int ftrace_regex_open(struct trace_array *tr, struct ftrace_ops *ops, int flag,
 		  struct inode *inode, struct file *file);
 ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
 			    size_t cnt, loff_t *ppos);
@@ -1077,7 +1078,7 @@ static inline unsigned long ftrace_location(unsigned long ip)
  * have them defined when ftrace is not enabled, but these
  * functions may still be called. Use a macro instead of inline.
  */
-#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; })
+#define ftrace_regex_open(tr, ops, flag, inode, file) ({ -ENODEV; })
 #define ftrace_set_early_filter(ops, buf, enable) do { } while (0)
 #define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; })
 #define ftrace_set_filter_ips(ops, ips, cnt, remove, reset) ({ -ENODEV; })
kernel/trace/ftrace.c +24 -20

103 lines not on this page · raw message

kernel/trace/trace.h +3 -2
index 74a7a50d1e78..3c111ca88e32 100644
@@ -1340,7 +1340,7 @@ extern void clear_ftrace_function_probes(struct trace_array *tr);
 int register_ftrace_command(struct ftrace_func_command *cmd);
 int unregister_ftrace_command(struct ftrace_func_command *cmd);
 
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
 				struct dentry *parent);
 void ftrace_destroy_filter_files(struct ftrace_ops *ops);
 
@@ -1363,11 +1363,12 @@ static inline void clear_ftrace_function_probes(struct trace_array *tr)
 {
 }
 
+static inline void ftrace_create_filter_files(struct trace_array *tr,
+					      struct dentry *parent) { }
 /*
  * The ops parameter passed in is usually undefined.
  * This must be a macro.
  */
-#define ftrace_create_filter_files(ops, parent) do { } while (0)
 #define ftrace_destroy_filter_files(ops) do { } while (0)
 #endif /* CONFIG_FUNCTION_TRACER && CONFIG_DYNAMIC_FTRACE */
 
kernel/trace/trace_functions.c +1 -1
index cd37f2013758..c879d43a5fbb 100644
@@ -101,7 +101,7 @@ int ftrace_create_function_files(struct trace_array *tr,
 		return ret;
 	}
 
-	ftrace_create_filter_files(tr->ops, parent);
+	ftrace_create_filter_files(tr, parent);
 
 	return 0;
 }
kernel/trace/trace_stack.c +1 -1
index 0aa2514a6593..e7f4e523587d 100644
@@ -499,7 +499,7 @@ stack_trace_filter_open(struct inode *inode, struct file *file)
 	struct ftrace_ops *ops = inode->i_private;
 
 	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
+	return ftrace_regex_open(NULL, ops, FTRACE_ITER_FILTER,
 				 inode, file);
 }
 
Signature · 3 lines
2.53.0

-- Steve