Received: by 2002:a05:6358:16cc:b0:ea:6187:17c9 with SMTP id r12csp473241rwl; Wed, 4 Jan 2023 23:20:28 -0800 (PST) X-Google-Smtp-Source: AMrXdXv1v1yY4PYJMvlCLbePvtkEJT92hRLd9lNboRnS6FdMfvRmFN82RF2ZWTiOqAi7FIilH4H4 X-Received: by 2002:a17:906:ae97:b0:7c1:2980:7fd1 with SMTP id md23-20020a170906ae9700b007c129807fd1mr40981636ejb.76.1672903228300; Wed, 04 Jan 2023 23:20:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672903228; cv=none; d=google.com; s=arc-20160816; b=Enuo7MekAsFYYf85khszOGQ7Xq0NVQbPF9U1f4bLazbD4aNGTFmBcpyU674ZD9SkSV 0vYA1HPwVlDT/B6AD8Es0fDLO4yqFIznyqCULbEdpLr4LG/xnMMuGIMGgNkVmTk5t/Qr tDcyqM8L8h6aKV8Um+qlEUfLMZRjNV6XhBJiCY0yWtkpJnXEnnprXJxYwKSe3Bxd8piS DXLfx1/+JPEJxXu6bZIgSqZ5HZ4JuleUVMvU8nA0PefUJdaLWJpRc8wvtTdf3XKNNSJE mOFWOd6GxbcnwoeJuPIh15QS26GLNxOxenlsCcL2XBBBlQSWZsCx04uZhTJrIKOuU6uG z7Yg== 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=fXPsnn9uFoGb5qFynw9QVIDa/aDO99QklPX5Zp6EkGc=; b=auyQgD+BsJbHlhlPg8ezJ1LwNLQDHHck8sLiQ7YMm5LkvilLKIrz/EjmAE8JRvIzHZ w1Wjf/phJQKbQzvmxYastkIfHXAtWJ0qfaGtmi+pmK9YfQrsFMqacabUsa2ginoEZ6Ma p96K5BHnMe1ZjaTXZq9EJn3oVlSLbB7igRPU1iH7ygWfsyvT1TSCZbEcbRM1DClqrGsi LTi17JNhz/qAZsp0ijcH+cVEvhWTgPsfnLGEAOugVMEtwaQ5LF6jtFJT2gsbbUM5rlHy 2XeVWYIiBC7vN6Eo2A6dsn4nXQGdAmY37Ol4/So3oxjG+sPs5tDGObI77k8LhjD6FYqu ir1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="duF/f+5e"; 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 bb11-20020a1709070a0b00b0078db371355esi30275906ejc.987.2023.01.04.23.20.03; Wed, 04 Jan 2023 23:20:28 -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="duF/f+5e"; 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 S231214AbjAEHRR (ORCPT + 99 others); Thu, 5 Jan 2023 02:17:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230423AbjAEHRL (ORCPT ); Thu, 5 Jan 2023 02:17:11 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 572E953724; Wed, 4 Jan 2023 23:17:10 -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 E738E6187F; Thu, 5 Jan 2023 07:17:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97C2EC433F0; Thu, 5 Jan 2023 07:17:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672903029; bh=1GKspHWwI8hefCzAlE4tVHVOSEMaUVMl7Mu48wMfSAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=duF/f+5enx0wWGApIN8lShAL50bOvJEYYelc0t72cVhgQI6/IvUlqM6TCGj4h5URe wyZP+52/mJuCKc3h/OVdNK8epnsNmCaeNAiTERIQnVa+qVOnElmmgO5oQ3OqZHX3V/ OGOWQYxcE5JL5mTdirUEZO6tnE+TH0oU70kqb9kK72Hec5zqh0EfkQnS/5ZUEdBOIp 8YSDTQc9EVkEB5pU15z9b7QY1OhWDUJZavIKkLn+9dLwoOL2s6rP4zHv7Md1GlqVMy 5vjjcT3R7algazI1VmFx/7euCxoIRbAp+J5n3UF8gXi73prcAP93evPRI8id3iD3vX Bi6IjJcHe1q1Q== From: Eric Biggers To: stable@vger.kernel.org Cc: linux-ext4@vger.kernel.org, syzbot+1a748d0007eeac3ab079@syzkaller.appspotmail.com, Theodore Ts'o Subject: [PATCH 5.15 07/10] ext4: don't set up encryption key during jbd2 transaction Date: Wed, 4 Jan 2023 23:13:56 -0800 Message-Id: <20230105071359.257952-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230105071359.257952-1-ebiggers@kernel.org> References: <20230105071359.257952-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 4c0d5778385cb3618ff26a561ce41de2b7d9de70 upstream. 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 Link: https://lore.kernel.org/r/20221106224841.279231-3-ebiggers@kernel.org Signed-off-by: Theodore Ts'o --- 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 bbbb6881f930b..bc209f3033273 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3647,8 +3647,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 33ce0e96868a7..0caa03805f0df 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1330,7 +1330,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 c4ec7a4fdaf75..1e6cc6c21d606 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); #ifdef 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.39.0