From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52978C7618A for ; Wed, 15 Mar 2023 12:29:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232557AbjCOM3U (ORCPT ); Wed, 15 Mar 2023 08:29:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232462AbjCOM26 (ORCPT ); Wed, 15 Mar 2023 08:28:58 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35CEA24C92 for ; Wed, 15 Mar 2023 05:27:59 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7C124B81DF6 for ; Wed, 15 Mar 2023 12:27:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BD33FC433D2; Wed, 15 Mar 2023 12:27:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1678883274; bh=a8MgM0fMPx7jmxyJgESNRpiBuYX3smxiGbxlv3S/QGk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C1r3IfaRXJBZlV9WiKbF9g5sTD0wQg/7wFl/N7syEIp2c60qF06w9cP05YuuDTc+0 kez+ChXJAXDUkQpvOcg3PIOvIrnMty9SsIMWp4lAT2aqXeKqoPGULFQ3X4JuRkREKQ +dnlKnkBWoDbn32/4ZMgMEqGkoAFQqmq2Dw0ozqo= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, syzbot+9d16c39efb5fade84574@syzkaller.appspotmail.com, Jan Kara , Theodore Tso , Sasha Levin Subject: [PATCH 5.15 082/145] ext4: Fix deadlock during directory rename Date: Wed, 15 Mar 2023 13:12:28 +0100 Message-Id: <20230315115741.695533464@linuxfoundation.org> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230315115738.951067403@linuxfoundation.org> References: <20230315115738.951067403@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Jan Kara [ Upstream commit 3c92792da8506a295afb6d032b4476e46f979725 ] As lockdep properly warns, we should not be locking i_rwsem while having transactions started as the proper lock ordering used by all directory handling operations is i_rwsem -> transaction start. Fix the lock ordering by moving the locking of the directory earlier in ext4_rename(). Reported-by: syzbot+9d16c39efb5fade84574@syzkaller.appspotmail.com Fixes: 0813299c586b ("ext4: Fix possible corruption when moving a directory") Link: https://syzkaller.appspot.com/bug?extid=9d16c39efb5fade84574 Signed-off-by: Jan Kara Link: https://lore.kernel.org/r/20230301141004.15087-1-jack@suse.cz Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/namei.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index aa689adeeafdf..c79c61002a620 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3827,10 +3827,20 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, return retval; } + /* + * We need to protect against old.inode directory getting converted + * from inline directory format into a normal one. + */ + if (S_ISDIR(old.inode->i_mode)) + inode_lock_nested(old.inode, I_MUTEX_NONDIR2); + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, &old.inlined); - if (IS_ERR(old.bh)) - return PTR_ERR(old.bh); + if (IS_ERR(old.bh)) { + retval = PTR_ERR(old.bh); + goto unlock_moved_dir; + } + /* * Check for inode number is _not_ due to possible IO errors. * We might rmdir the source, keep it as pwd of some process @@ -3887,11 +3897,6 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir)) goto end_rename; } - /* - * We need to protect against old.inode directory getting - * converted from inline directory format into a normal one. - */ - inode_lock_nested(old.inode, I_MUTEX_NONDIR2); retval = ext4_rename_dir_prepare(handle, &old); if (retval) { inode_unlock(old.inode); @@ -4021,12 +4026,15 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, } else { ext4_journal_stop(handle); } - if (old.dir_bh) - inode_unlock(old.inode); release_bh: brelse(old.dir_bh); brelse(old.bh); brelse(new.bh); + +unlock_moved_dir: + if (S_ISDIR(old.inode->i_mode)) + inode_unlock(old.inode); + return retval; } -- 2.39.2