mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
eventfs: Fix use-after-free in eventfs_remove_rec()
eventfs_remove_rec() recursively removes the child at the current loop
position. After the recursive call returns, list_for_each_entry() advances
by reading list.next from the removed child.
If free_ei() drops the final reference, release_ei() reuses the list/rcu
union to queue an SRCU callback. The child may be freed before that read.
The eventfs_mutex serializes list updates, but it does not keep the removed
child alive or prevent the SRCU callback from running.
Use list_for_each_entry_safe() to save the next sibling before recursively
removing the current child.
Cc: stable@vger.kernel.org
Fixes: 43aa6f97c2 ("eventfs: Get rid of dentry pointers without refcounts")
Link: https://patch.msgid.link/20260806022719.375354-1-shuangpeng.kernel@gmail.com
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
committed by
Steven Rostedt
parent
075b74841b
commit
fd73b69170
@@ -822,7 +822,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
|
||||
*/
|
||||
static void eventfs_remove_rec(struct eventfs_inode *ei, int level)
|
||||
{
|
||||
struct eventfs_inode *ei_child;
|
||||
struct eventfs_inode *ei_child, *tmp;
|
||||
|
||||
/*
|
||||
* Check recursion depth. It should never be greater than 3:
|
||||
@@ -835,7 +835,7 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, int level)
|
||||
return;
|
||||
|
||||
/* search for nested folders or files */
|
||||
list_for_each_entry(ei_child, &ei->children, list)
|
||||
list_for_each_entry_safe(ei_child, tmp, &ei->children, list)
|
||||
eventfs_remove_rec(ei_child, level + 1);
|
||||
|
||||
list_del_rcu(&ei->list);
|
||||
|
||||
Reference in New Issue
Block a user