Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp839359rwb; Sun, 6 Nov 2022 14:53:30 -0800 (PST) X-Google-Smtp-Source: AMsMyM75LwAXlDU4wOetunAGlRvjy4kdgtHGkBwrNjPvQWSjxZqmyVtV6rNEqPjRP1DFcNqMDamc X-Received: by 2002:a50:fd12:0:b0:463:cb99:5b1 with SMTP id i18-20020a50fd12000000b00463cb9905b1mr29561290eds.256.1667775210522; Sun, 06 Nov 2022 14:53:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667775210; cv=none; d=google.com; s=arc-20160816; b=nccbLVBsJkRPAmOkzFzfDBmN8NOp/YmGLjXzc3BaImuH8muWWUaeGw3qwAHBkKk6hz nbEkiOU14XSMDqUULZLW9Ipe/326vWiEWRB5uI8rIgGeR8clmKjApRt+mFJxKeb4WmnF 20UMfOS6K923cHJOjbTQfIIqIculq66v0HTglqr1YaCHVBbHVTH/w/cV0YV9xhZClhoN jJDIjt/2OejpDHhYsJ63xUHEv2t5gYHixyRmya7+sxHPakFAUcz2jzaZaB/Agh83AF3j x3q8wwiH2vp10uEkAMWcjXUf0r4nYjW061sOlsHx0vzXSgMRP98gItu1q15oY1LnM/XK OYrQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6xjsLN/Wd/O+jTWApN692zPQiXdvrfG0XZX2tuLYkw4=; b=ikn1cHZh1hmzEWvQVhgVXLJXgP8vj72l7lkb35pBWgIyqv8W3fN/QXc5XXdQlPd+pD AKcbG9Qcmzp2Y2lexaPzgJPSaANjxIQ/rrE17WGtKkjp1B1ukTW2q+FKKgteO5TgzGSt eRl/hcUvK14ir2WGE8xQ/dzhFWTDl6VJJWftBv5mb786/DNj2Ab/WXa/A3Z7lxqtbNBs h4Qgzbo/6VLvSn9M4+W2z76pikbNHt/ok0ryUPGHa0nYbdYdsEbc66hgJwvbDUAj8oTd 9uFK9Z7eUcI89FeD5/fILmmvcJpXYG+m6auLK2CP56EsfqORba6OW/Ie0dr86M8CY01Z dQKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YobhkydW; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id dd3-20020a1709069b8300b00787796077a0si7558484ejc.429.2022.11.06.14.53.06; Sun, 06 Nov 2022 14:53:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YobhkydW; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230211AbiKFWwg (ORCPT + 99 others); Sun, 6 Nov 2022 17:52:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230080AbiKFWwg (ORCPT ); Sun, 6 Nov 2022 17:52:36 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C04410069; Sun, 6 Nov 2022 14:52:35 -0800 (PST) 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 dfw.source.kernel.org (Postfix) with ESMTPS id DBC8F60D3F; Sun, 6 Nov 2022 22:52:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 20E4AC433D7; Sun, 6 Nov 2022 22:52:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1667775154; bh=viwho2/kAwPo7/z1JDbp/8F8oyoXxKvO2xM8aVptWMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YobhkydWWDLpBVk+FwGbsTVYA6XoRPfXPw1ltkPns+iXA98RZ+VpcU36Hf1mqJrYp 9KDkhGC2x4JZTzgVhU+VMLcWqbmyWbGByFEfwS/bPvwEKxKCP1uViihefXu9d8FDvA EaVVwZoHW7m/UJDMOmzUB4QvQtWyohzxPThz2DcXKNvO9zO7GsttO5mWDZ2ufLUmJ+ 4XhAkqrEeFrxA4yu34z8UxO0zF+4xCi0YNFHnRJF7INp0UzBSD44qYWFu5eE94Gh17 9zkvbmABEtFtmJIAFrV197PpbJNgvGshRdguSFjLB36Sd4jnIuB2lYL0NzA5hqi49+ 0lJn5IPlubFYA== From: Eric Biggers To: linux-ext4@vger.kernel.org Cc: linux-fscrypt@vger.kernel.org, Harshad Shirwadkar , stable@vger.kernel.org, syzbot+1a748d0007eeac3ab079@syzkaller.appspotmail.com Subject: [PATCH 2/7] ext4: don't set up encryption key during jbd2 transaction Date: Sun, 6 Nov 2022 14:48:36 -0800 Message-Id: <20221106224841.279231-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221106224841.279231-1-ebiggers@kernel.org> References: <20221106224841.279231-1-ebiggers@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Eric Biggers Commit a80f7fcf1867 ("ext4: fixup ext4_fc_track_* functions' signature") extended the scope of the transaction in ext4_unlink() too far, making it include the call to ext4_find_entry(). However, ext4_find_entry() can deadlock when called from within a transaction because it may need to set up the directory's encryption key. Fix this by restoring the transaction to its original scope. Reported-by: syzbot+1a748d0007eeac3ab079@syzkaller.appspotmail.com Fixes: a80f7fcf1867 ("ext4: fixup ext4_fc_track_* functions' signature") Cc: # v5.10+ Signed-off-by: Eric Biggers --- fs/ext4/ext4.h | 4 ++-- fs/ext4/fast_commit.c | 2 +- fs/ext4/namei.c | 44 +++++++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8d5453852f98e..acaa951ef1886 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3619,8 +3619,8 @@ extern void ext4_initialize_dirent_tail(struct buffer_head *bh, unsigned int blocksize); extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode, struct buffer_head *bh); -extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name, - struct inode *inode); +extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name, + struct inode *inode, struct dentry *dentry); extern int __ext4_link(struct inode *dir, struct inode *inode, struct dentry *dentry); diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index 6d98f2b39b775..da0c8228cf9c3 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1397,7 +1397,7 @@ static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl, return 0; } - ret = __ext4_unlink(NULL, old_parent, &entry, inode); + ret = __ext4_unlink(old_parent, &entry, inode, NULL); /* -ENOENT ok coz it might not exist anymore. */ if (ret == -ENOENT) ret = 0; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c08c0aba18836..a789ea9b61a09 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3204,14 +3204,20 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) return retval; } -int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name, - struct inode *inode) +int __ext4_unlink(struct inode *dir, const struct qstr *d_name, + struct inode *inode, + struct dentry *dentry /* NULL during fast_commit recovery */) { int retval = -ENOENT; struct buffer_head *bh; struct ext4_dir_entry_2 *de; + handle_t *handle; int skip_remove_dentry = 0; + /* + * Keep this outside the transaction; it may have to set up the + * directory's encryption key, which isn't GFP_NOFS-safe. + */ bh = ext4_find_entry(dir, d_name, &de, NULL); if (IS_ERR(bh)) return PTR_ERR(bh); @@ -3228,7 +3234,14 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) skip_remove_dentry = 1; else - goto out; + goto out_bh; + } + + handle = ext4_journal_start(dir, EXT4_HT_DIR, + EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); + if (IS_ERR(handle)) { + retval = PTR_ERR(handle); + goto out_bh; } if (IS_DIRSYNC(dir)) @@ -3237,12 +3250,12 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name if (!skip_remove_dentry) { retval = ext4_delete_entry(handle, dir, de, bh); if (retval) - goto out; + goto out_handle; dir->i_ctime = dir->i_mtime = current_time(dir); ext4_update_dx_flag(dir); retval = ext4_mark_inode_dirty(handle, dir); if (retval) - goto out; + goto out_handle; } else { retval = 0; } @@ -3255,15 +3268,17 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name ext4_orphan_add(handle, inode); inode->i_ctime = current_time(inode); retval = ext4_mark_inode_dirty(handle, inode); - -out: + if (dentry && !retval) + ext4_fc_track_unlink(handle, dentry); +out_handle: + ext4_journal_stop(handle); +out_bh: brelse(bh); return retval; } static int ext4_unlink(struct inode *dir, struct dentry *dentry) { - handle_t *handle; int retval; if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) @@ -3281,16 +3296,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) if (retval) goto out_trace; - handle = ext4_journal_start(dir, EXT4_HT_DIR, - EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) { - retval = PTR_ERR(handle); - goto out_trace; - } - - retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry)); - if (!retval) - ext4_fc_track_unlink(handle, dentry); + retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry); #if IS_ENABLED(CONFIG_UNICODE) /* VFS negative dentries are incompatible with Encoding and * Case-insensitiveness. Eventually we'll want avoid @@ -3301,8 +3307,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) if (IS_CASEFOLDED(dir)) d_invalidate(dentry); #endif - if (handle) - ext4_journal_stop(handle); out_trace: trace_ext4_unlink_exit(dentry, retval); -- 2.38.1