Received: by 2002:a05:6358:16cc:b0:ea:6187:17c9 with SMTP id r12csp4192507rwl; Sat, 7 Jan 2023 12:57:17 -0800 (PST) X-Google-Smtp-Source: AMrXdXstX1cL1DZNzwb9aDY0QNwhAF8a+/hr1cahmN/VePP1pNOHRfACjcapy4KJ3a/K0EOw4kzO X-Received: by 2002:a17:902:c643:b0:192:4d6a:2ac8 with SMTP id s3-20020a170902c64300b001924d6a2ac8mr53159528pls.56.1673125036982; Sat, 07 Jan 2023 12:57:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673125036; cv=none; d=google.com; s=arc-20160816; b=fEqsyHctpi3oFMYYT/c5mGwqiwA2SF2cB71rjDgTWB8vo6SbWw+Ilq7FdWQgxCY5lG uFaSw3McqJN+WAvlEfjHwo2Ghza6F0ixiDvp4bzEBeGMJJpFVXxTDxhbHX1YdCq/7074 1s9f8CbIx2kk9MvmCegKLDUtgZvv60S/MTnmViJerH3ptbosz1udKnwDEwwnvywR5F/2 FE7pkkVxRlhEGfKUlnYIlp4QoLuacZFW0wZPlgHD1q3Nx9NZhajxhecFZSv66IvgElkN 3pJE3FEZ9A/MNFiJXvNEgqMrZ3tLW2TUw9CIK4lc+9bqQN5DzmudhC8HmpbFAXbR22DN flWw== 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=VSI0H06J7Jr+VoU/WfS3O3zMwdq97Zt16ZZta0zovcs=; b=WTxp+09WNkTILbTGW3DD+J5hze5LBlNm3+C0WRpRuCnGzRw1ZqNakuf+q5qUreXhUZ kRMFtuhdmGVLJGtAhOay90IvGCzMHoUPi5KZspZ2g+lw5gkrW7kgJ+t3hvmjhB5HnD6C V0auDEbTJ7/z7CUNSxTEZG9vPDjfK40E7Sqw1q3rn/Khd2rOKhfTB+o3YIkP7k44Z03A F26yriVMd3HEllih8v7wT607WotwE3cOg+NHfXw0HJvIjX75nmSY3IBekXDSShU8kvQp qfydEgq1kVDSZabclYsqdJfMLrOw98Dqda5GQR9qmXmHlKhlDbE+HooXTBm3atwySx2b Lmmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="OW/brwgy"; 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 i5-20020a17090332c500b00179f8a3f838si5472484plr.593.2023.01.07.12.57.04; Sat, 07 Jan 2023 12:57:16 -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="OW/brwgy"; 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 S229785AbjAGUhx (ORCPT + 99 others); Sat, 7 Jan 2023 15:37:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232479AbjAGUht (ORCPT ); Sat, 7 Jan 2023 15:37:49 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 573543B907; Sat, 7 Jan 2023 12:37:48 -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 sin.source.kernel.org (Postfix) with ESMTPS id A6974CE0AC8; Sat, 7 Jan 2023 20:37:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D0BBC433F1; Sat, 7 Jan 2023 20:37:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673123864; bh=VSzHJfYKKrxC07hwQNVj/0slDjdR/S4juXYQrZhQd4w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OW/brwgyWD9znGhMDZCEy+hbuDmWy0s4riViQcpyDc2PtTjYD12IZfQfeK8r9JPe0 tUNzsAw+oh5rWFSSLe+iLV/3S2em4Mi5bn/pnHWafpj2NGc5LSq+GqogVyeeDDBmJ+ 9D7OC9uW/BsUaA8v6A+dfyjcVJ7x1cD6kvGUQ280qe5WRjerMtHg+Dh766VGCxnk3h NCbf2y6XoMT/5M6zOg0PBusWxo8o5tzFWifLiCIan3bbpSHYU55q1fKC/p2X1EjyOh A2UifectQRIkdibkcT3sl46If2a8ZiZZJOD6HZ7HAd3/awXWfnAwKZ4N/sv59jPEGp 8mpn8lmUG9RLw== 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.10 2/2] ext4: don't set up encryption key during jbd2 transaction Date: Sat, 7 Jan 2023 12:37:13 -0800 Message-Id: <20230107203713.158042-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230107203713.158042-1-ebiggers@kernel.org> References: <20230107203713.158042-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 fb9c9e1813bc5..81dc61f1c557f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3486,8 +3486,8 @@ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode, extern int ext4_ci_compare(const struct inode *parent, const struct qstr *fname, const struct qstr *entry, bool quick); -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 e26020598e194..be96f5ccc55dd 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1295,7 +1295,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 c17d5f399f9ea..e296b3587bb38 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3244,14 +3244,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); @@ -3268,7 +3274,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)) @@ -3277,12 +3290,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; } @@ -3295,15 +3308,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)))) @@ -3321,16 +3336,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 @@ -3341,8 +3347,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