Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp4514076ybz; Tue, 21 Apr 2020 01:55:39 -0700 (PDT) X-Google-Smtp-Source: APiQypJoOipEl5YEtFrG+8eKpJazUG90RbcgWeX/kt+Ikyw0FPRJQTFL/zrq2lnynYtPSzAUj9PX X-Received: by 2002:a05:6402:17e3:: with SMTP id t3mr18055807edy.203.1587459339597; Tue, 21 Apr 2020 01:55:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587459339; cv=none; d=google.com; s=arc-20160816; b=0ROCdl/lF6ovbcbN59a19UWhoDILn6dsEmrJVmCQ8pE8flvReJaprmer9nVJ+xyToq 5GvHnYyP081192gNtywdFqFTkw1AfZfQIba/w1Q+tRTWpCD+6CoWB9kEEnbKBi8XzSR0 4bXgX+F6k+1Y2NPOcg6HP56h1sZddenjqA+T1pIpAx6abbLu3AtaoZnP08V07mBtGCoi mcq9LswJrtegi8uoRjfFQqZXQmkn7Hvp++LeZiHpr+lIUOzWuUQcW9RK+tzRBIjkcKQ+ uiJz87qI978l7DsPv6d8bzWCZT21TgMJp8+1rckoZ2/4KCLA360xZBlMPGivNYC4eRe/ zfHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=UqtKXNgQwMSzTZ7fxD0/Lv7MBBCD6+ruTRuLuNKl7Lc=; b=TbPp7nEuG0rFN/OYE0f3FfsZUm0FJp+jkd78A3Tc09rAck4qT4GaRgf+Xubkm7VFlz A+YBO/0mlrogjAsNzdC52zQZhuvORWhLx0QssDrn4PQGXmSXDHGbEEH5NHDFdHjJuzB6 A1MQCuD04tRu9FcNVy4ytU5mkGrZwEfMB+fjCOZtqCldt9+XMhF4X8IRqqoN5y4MLCOA 0UHlQE3f9dExAKP2jHFhtJg2dGDdqRZJrNyS1jjJ99TAgEfBSy6Ypy0Buk3FAe/IqjvJ 6ut/C7K4TmeITNTsiR6+PNX2eqQN2WtYaz7QoS18gpQ5jrEdkLU0SUjGnNYqKzm60CXi nzcw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y18si1258312edt.554.2020.04.21.01.55.16; Tue, 21 Apr 2020 01:55:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727911AbgDUIyu (ORCPT + 99 others); Tue, 21 Apr 2020 04:54:50 -0400 Received: from mx2.suse.de ([195.135.220.15]:41498 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726052AbgDUIyu (ORCPT ); Tue, 21 Apr 2020 04:54:50 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id CC380ACD0; Tue, 21 Apr 2020 08:54:47 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 395121E124D; Tue, 21 Apr 2020 10:54:48 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , , Eric Sandeen , Jan Kara Subject: [PATCH 3/3] ext4: Avoid freeing inodes on dirty list Date: Tue, 21 Apr 2020 10:54:45 +0200 Message-Id: <20200421085445.5731-4-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200421085445.5731-1-jack@suse.cz> References: <20200421085445.5731-1-jack@suse.cz> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org When we are evicting inode with journalled data, we may race with transaction commit in the following way: CPU0 CPU1 jbd2_journal_commit_transaction() evict(inode) inode_io_list_del() inode_wait_for_writeback() process BJ_Forget list __jbd2_journal_insert_checkpoint() __jbd2_journal_refile_buffer() __jbd2_journal_unfile_buffer() if (test_clear_buffer_jbddirty(bh)) mark_buffer_dirty(bh) __mark_inode_dirty(inode) ext4_evict_inode(inode) frees the inode This results in use-after-free issues in the writeback code (or the assertion added in the previous commit triggering). Fix the problem by removing inode from writeback lists once all the page cache is evicted and so inode cannot be added to writeback lists again. Signed-off-by: Jan Kara --- fs/ext4/inode.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e416096fc081..d8a9d3da678c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -220,6 +220,16 @@ void ext4_evict_inode(struct inode *inode) ext4_begin_ordered_truncate(inode, 0); truncate_inode_pages_final(&inode->i_data); + /* + * For inodes with journalled data, transaction commit could have + * dirtied the inode. Flush worker is ignoring it because of I_FREEING + * flag but we still need to remove the inode from the writeback lists. + */ + if (!list_empty_careful(&inode->i_io_list)) { + WARN_ON_ONCE(!ext4_should_journal_data(inode)); + inode_io_list_del(inode); + } + /* * Protect us against freezing - iput() caller didn't have to have any * protection against it -- 2.16.4