We have the reference count that we can use to see if the inode is alive. Signed-off-by: Josef Bacik --- security/landlock/fs.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/security/landlock/fs.c b/security/landlock/fs.c index 0bade2c5aa1d..fc7e577b56e1 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -1280,23 +1280,8 @@ static void hook_sb_delete(struct super_block *const sb) list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { struct landlock_object *object; - /* Only handles referenced inodes. */ - if (!icount_read(inode)) - continue; - - /* - * Protects against concurrent modification of inode (e.g. - * from get_inode_object()). - */ spin_lock(&inode->i_lock); - /* - * Checks I_FREEING and I_WILL_FREE to protect against a race - * condition when release_inode() just called iput(), which - * could lead to a NULL dereference of inode->security or a - * second call to iput() for the same Landlock object. Also - * checks I_NEW because such inode cannot be tied to an object. - */ - if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) { + if (inode->i_state & I_NEW) { spin_unlock(&inode->i_lock); continue; } @@ -1308,10 +1293,11 @@ static void hook_sb_delete(struct super_block *const sb) spin_unlock(&inode->i_lock); continue; } - /* Keeps a reference to this inode until the next loop walk. */ - __iget(inode); spin_unlock(&inode->i_lock); + if (!igrab(inode)) + continue; + /* * If there is no concurrent release_inode() ongoing, then we * are in charge of calling iput() on this inode, otherwise we -- 2.49.0