From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
To: Steven Rostedt <steven@rostedt.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Linux Trace Kernel <linux-trace-kernel@vger.kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Subject: Re: [PATCH] eventfs: Use children field for rcu head and add memory barriers
Date: Sat, 8 Aug 2026 07:15:06 +0900 [thread overview]
Message-ID: <20260808071506.cacd0c21059c942a5d2d173b@kernel.org> (raw)
In-Reply-To: <20260807170408.2d324df5@gandalf.local.home>
On Fri, 7 Aug 2026 17:04:08 -0400
Steven Rostedt <steven@rostedt.org> wrote:
> From: Steven Rostedt <rostedt@goodmis.org>
>
> When an eventfs inode is freed, it sets ei->is_freed and then uses its
> ei->list to add it to the srcu link list as the list field is a union with
> the rcu list head. As the ei->list is used to iterate over an SRCU
> protected list without taking the eventfs_mutex, there's nothing stopping
> the iteration over that list to see the ei->rcu instead of the ei->list
> and it will read a corrupt target.
>
> To fix this, change the union of the rcu list head with the children list.
> On freeing the eventfs inode, set the is_free and execute a smp_wmb()
> before adding the eventfs inode to the SRCU list.
>
> On iteration of the ei->children list, at the start, execute a smp_rmb()
> and then read the is_freed of the ei to see if the children list is still
> valid. If is_freed is set, then the ei_child read is not valid and the
> loop should exit immediately.
>
Looks good to me.
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
The critical issues Sashiko mentioned will be fixed by Shuangpeng's patch[1].
[1] https://lore.kernel.org/all/20260806022719.375354-1-shuangpeng.kernel@gmail.com/
Thank you,
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/#/patchset/20260806022719.375354-1-shuangpeng.kernel%40gmail.com
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
> fs/tracefs/event_inode.c | 24 ++++++++++++++++++++++++
> fs/tracefs/internal.h | 4 ++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
> index 39c7a34531e8..677c39b0d62f 100644
> --- a/fs/tracefs/event_inode.c
> +++ b/fs/tracefs/event_inode.c
> @@ -124,6 +124,16 @@ static inline void put_ei(struct eventfs_inode *ei)
> static inline void free_ei(struct eventfs_inode *ei)
> {
> if (ei) {
> + WARN_ON_ONCE(!list_empty(&ei->children));
> + /*
> + * The ei should have no children if it is being freed.
> + * The SRCU iteration has a smp_rmb() to make sure it
> + * sees a child (that may have already been freed)
> + * before it reads is_free. If is_free is set, it must
> + * not use the child it acquired from ei->children, as
> + * the list may be used for SRCU.
> + */
> + smp_wmb();
> ei->is_freed = 1;
> put_ei(ei);
> }
> @@ -627,6 +637,20 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx)
> list_for_each_entry_srcu(ei_child, &ei->children, list,
> srcu_read_lock_held(&eventfs_srcu)) {
>
> + /*
> + * If the ei is being freed, then the ei->children may be
> + * being used as the rcu list, which means the next element
> + * may be garbage. The ei->is_free is set before switching
> + * the ei->children over to ei->rcu. The read memory barrier
> + * here makes sure the ei_child is read before is_free is
> + * updated.
> + *
> + * Matches the smp_wmb() in put_ei()
> + */
> + smp_rmb();
> + if (ei->is_freed)
> + return -EINVAL;
> +
> if (c > 0) {
> c--;
> continue;
> diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
> index a4a7f8431aff..c61481d04c8e 100644
> --- a/fs/tracefs/internal.h
> +++ b/fs/tracefs/internal.h
> @@ -46,11 +46,11 @@ struct eventfs_attr {
> * @ino: The saved inode number
> */
> struct eventfs_inode {
> + struct list_head list;
> union {
> - struct list_head list;
> + struct list_head children;
> struct rcu_head rcu;
> };
> - struct list_head children;
> const struct eventfs_entry *entries;
> const char *name;
> struct eventfs_attr *entry_attrs;
> --
> 2.53.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
next prev parent reply other threads:[~2026-08-07 22:15 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 21:04 [PATCH] eventfs: Use children field for rcu head and add memory barriers Steven Rostedt
2026-08-07 22:15 ` Masami Hiramatsu [this message]
2026-08-08 0:00 ` Steven Rostedt
-- strict thread matches above, loose matches on Subject: below --
2026-08-08 13:42 Steven Rostedt
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=20260808071506.cacd0c21059c942a5d2d173b@kernel.org \
--to=mhiramat@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=steven@rostedt.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.