From: Vincent Donnefort <vdonnefort@google.com>
To: rostedt@goodmis.org, mhiramat@kernel.org,
linux-trace-kernel@vger.kernel.org
Cc: mathieu.desnoyers@efficios.com, kernel-team@android.com,
linux-kernel@vger.kernel.org,
Vincent Donnefort <vdonnefort@google.com>
Subject: [PATCH v4 01/18] tracing/remotes: Gate tracefs files opening on trace remote registration
Date: Tue, 4 Aug 2026 15:03:16 +0100 [thread overview]
Message-ID: <20260804140333.797210-2-vdonnefort@google.com> (raw)
In-Reply-To: <20260804140333.797210-1-vdonnefort@google.com>
Currently, if a remote fails to register, its resources will leak and
will not be properly torn down.
To prevent a user accessing a remote tracefs that is about to be
destroyed, keep track of the registered remotes in a global list,
similarly to trace instances. Gate the tracefs open function based on
the presence of the remote in that list.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c
index e6724f947170..ce2d517183b7 100644
--- a/kernel/trace/trace_remote.c
+++ b/kernel/trace/trace_remote.c
@@ -39,6 +39,7 @@ struct trace_remote_iterator {
};
struct trace_remote {
+ struct list_head node;
struct trace_remote_callbacks *cbs;
void *priv;
struct trace_buffer *trace_buffer;
@@ -57,6 +58,9 @@ struct trace_remote {
bool tracing_on;
};
+static DEFINE_MUTEX(trace_remotes_lock);
+static LIST_HEAD(trace_remotes);
+
static bool trace_remote_loaded(struct trace_remote *remote)
{
return !!remote->trace_buffer;
@@ -170,6 +174,60 @@ static void trace_remote_reset(struct trace_remote *remote, int cpu)
trace_remote_try_unload(remote);
}
+static int trace_remote_tracefs_open(struct inode *inode, struct file *filp)
+{
+ void *i_private = inode->i_private;
+ struct trace_remote *r;
+
+ if (!i_private)
+ return -ENODEV;
+
+ guard(mutex)(&trace_remotes_lock);
+
+ /* i_private is either a struct trace_remote or a struct remote_event */
+ list_for_each_entry(r, &trace_remotes, node) {
+ if (r == i_private)
+ return 0;
+ if (!r->events)
+ continue;
+ if (i_private >= (void *)r->events &&
+ i_private < (void *)(r->events + r->nr_events))
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+#define DEFINE_TRACE_REMOTE_ATTRIBUTE_FUNCS(__name) \
+static int __name ## _open(struct inode *inode, struct file *file) \
+{ \
+ int ret = trace_remote_tracefs_open(inode, file); \
+ \
+ if (ret) \
+ return ret; \
+ \
+ return single_open(file, __name ## _show, inode->i_private); \
+}
+
+#define DEFINE_TRACE_REMOTE_ATTRIBUTE(__name) \
+DEFINE_TRACE_REMOTE_ATTRIBUTE_FUNCS(__name) \
+static const struct file_operations __name ## _fops = { \
+ .open = __name ## _open, \
+ .read = seq_read, \
+ .write = __name ## _write, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
+#define DEFINE_TRACE_REMOTE_SHOW_ATTRIBUTE(__name) \
+DEFINE_TRACE_REMOTE_ATTRIBUTE_FUNCS(__name) \
+static const struct file_operations __name ## _fops = { \
+ .open = __name ## _open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
static ssize_t
tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
@@ -198,7 +256,7 @@ static int tracing_on_show(struct seq_file *s, void *unused)
return 0;
}
-DEFINE_SHOW_STORE_ATTRIBUTE(tracing_on);
+DEFINE_TRACE_REMOTE_ATTRIBUTE(tracing_on);
static ssize_t buffer_size_kb_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos)
@@ -235,7 +293,7 @@ static int buffer_size_kb_show(struct seq_file *s, void *unused)
return 0;
}
-DEFINE_SHOW_STORE_ATTRIBUTE(buffer_size_kb);
+DEFINE_TRACE_REMOTE_ATTRIBUTE(buffer_size_kb);
static int trace_remote_get(struct trace_remote *remote, int cpu)
{
@@ -593,6 +651,11 @@ static int trace_pipe_open(struct inode *inode, struct file *filp)
struct trace_remote *remote = inode->i_private;
struct trace_remote_iterator *iter;
int cpu = tracing_get_cpu(inode);
+ int ret;
+
+ ret = trace_remote_tracefs_open(inode, filp);
+ if (ret)
+ return ret;
guard(mutex)(&remote->lock);
@@ -734,22 +797,26 @@ static int trace_open(struct inode *inode, struct file *filp)
int cpu = tracing_get_cpu(inode);
int ret;
+ ret = trace_remote_tracefs_open(inode, filp);
+ if (ret)
+ return ret;
+
if (!(filp->f_mode & FMODE_READ))
return 0;
+ ret = seq_open(filp, &trace_sops);
+ if (ret)
+ return ret;
+
guard(mutex)(&remote->lock);
iter = trace_remote_iter(remote, cpu, TRI_NONCONSUMING);
- if (IS_ERR(iter))
+ if (IS_ERR(iter)) {
+ seq_release(inode, filp);
return PTR_ERR(iter);
-
- ret = seq_open(filp, &trace_sops);
- if (ret) {
- trace_remote_iter_free(iter);
- return ret;
}
- ((struct seq_file *)filp->private_data)->private = (void *)iter;
+ ((struct seq_file *)filp->private_data)->private = iter;
return 0;
}
@@ -932,8 +999,12 @@ int trace_remote_register(const char *name, struct trace_remote_callbacks *cbs,
}
ret = cbs->init ? cbs->init(remote->dentry, priv) : 0;
- if (ret)
+ if (ret) {
pr_err("Init failed for trace remote '%s' (%d)\n", name, ret);
+ } else {
+ guard(mutex)(&trace_remotes_lock);
+ list_add(&remote->node, &trace_remotes);
+ }
return ret;
}
@@ -1069,7 +1140,7 @@ static ssize_t remote_event_enable_write(struct file *filp, const char __user *u
return count;
}
-DEFINE_SHOW_STORE_ATTRIBUTE(remote_event_enable);
+DEFINE_TRACE_REMOTE_ATTRIBUTE(remote_event_enable);
static int remote_event_id_show(struct seq_file *s, void *unused)
{
@@ -1079,7 +1150,7 @@ static int remote_event_id_show(struct seq_file *s, void *unused)
return 0;
}
-DEFINE_SHOW_ATTRIBUTE(remote_event_id);
+DEFINE_TRACE_REMOTE_SHOW_ATTRIBUTE(remote_event_id);
static int remote_event_format_show(struct seq_file *s, void *unused)
{
@@ -1108,7 +1179,7 @@ static int remote_event_format_show(struct seq_file *s, void *unused)
return 0;
}
-DEFINE_SHOW_ATTRIBUTE(remote_event_format);
+DEFINE_TRACE_REMOTE_SHOW_ATTRIBUTE(remote_event_format);
static int remote_event_callback(const char *name, umode_t *mode, void **data,
const struct file_operations **fops)
@@ -1194,6 +1265,7 @@ static ssize_t remote_events_dir_enable_read(struct file *filp, char __user *ubu
}
static const struct file_operations remote_events_dir_enable_fops = {
+ .open = trace_remote_tracefs_open,
.write = remote_events_dir_enable_write,
.read = remote_events_dir_enable_read,
};
@@ -1218,6 +1290,7 @@ remote_events_dir_header_page_read(struct file *filp, char __user *ubuf, size_t
}
static const struct file_operations remote_events_dir_header_page_fops = {
+ .open = trace_remote_tracefs_open,
.read = remote_events_dir_header_page_read,
};
@@ -1241,6 +1314,7 @@ remote_events_dir_header_event_read(struct file *filp, char __user *ubuf, size_t
}
static const struct file_operations remote_events_dir_header_event_fops = {
+ .open = trace_remote_tracefs_open,
.read = remote_events_dir_header_event_read,
};
--
2.55.0.571.g244d577d93-goog
next prev parent reply other threads:[~2026-08-04 14:03 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 14:03 [PATCH v4 00/18] tracing/remotes: Add printk, dump_on_panic and boot parameters Vincent Donnefort
2026-08-04 14:03 ` Vincent Donnefort [this message]
2026-08-04 14:03 ` [PATCH v4 02/18] tracing/remotes: Release tracefs,eventfs on registration failure Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 03/18] tracing/remotes: Use kstrtobool for boolean tracefs files Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 04/18] tracing/remotes: Use a single per-remote polling work Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 05/18] tracing/simple_ring_buffer: Add support for compressed length Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 06/18] tracing/remotes: Add dmesg tracefs file Vincent Donnefort
2026-08-10 22:42 ` Steven Rostedt
2026-08-11 9:09 ` Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 07/18] tracing/remotes: selftests: Add a test for the " Vincent Donnefort
2026-08-10 22:46 ` Steven Rostedt
2026-08-04 14:03 ` [PATCH v4 08/18] tracing/remotes: selftests: Prefix hypervisor folder Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 09/18] ring-buffer: Use irqsave for the reader lock in ring_buffer_poll_remote Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 10/18] ring-buffer: Use panic-friendly locking in ring_buffer_iter interface Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 11/18] ring-buffer: Add ring_buffer_read_remote_meta_page() Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 12/18] ring-buffer: Add kerneldoc for ring_buffer_poll_remote Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 13/18] tracing/remotes: Add dump_on_panic tracefs file Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 14/18] tracing/remotes: selftests: Add a test for the " Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 15/18] tracing/remotes: Add poll_ms " Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 16/18] tracing/remotes: Add trace_remote cmdline options Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 17/18] Documentation: tracing/remotes: Add detailed tracefs layout Vincent Donnefort
2026-08-04 14:03 ` [PATCH v4 18/18] Documentation/kernel-parameters: Add trace_remote Vincent Donnefort
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260804140333.797210-2-vdonnefort@google.com \
--to=vdonnefort@google.com \
--cc=kernel-team@android.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.