From: Shuangpeng Bai <[email protected]>

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: [email protected]
Fixes: 43aa6f97c2d0 ("eventfs: Get rid of dentry pointers without refcounts")
Link: 
https://patch.msgid.link/[email protected]
Signed-off-by: Shuangpeng Bai <[email protected]>
Acked-by: Masami Hiramatsu (Google) <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
(cherry picked from commit fd73b691702170d37d66f4b0278530cea8ed419a)

https://virtuozzo.atlassian.net/browse/VSTOR-154529
Feature: fix ms/tracefs

Signed-off-by: Eva Kurchatova <[email protected]>
---
 fs/tracefs/event_inode.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index ce61795a7ed5..cc08218d6e26 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -848,7 +848,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:
@@ -861,7 +861,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);
-- 
2.56.0

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to