Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp4513911ybz; Tue, 21 Apr 2020 01:55:21 -0700 (PDT) X-Google-Smtp-Source: APiQypJTN2l7GT53lymV7sXGoHt2C8wN5qofG1B/P5WiarUSH0WmgcGOjC/DWSpLsHageiONaqxh X-Received: by 2002:a17:906:1a06:: with SMTP id i6mr19662888ejf.90.1587459321710; Tue, 21 Apr 2020 01:55:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587459321; cv=none; d=google.com; s=arc-20160816; b=cIyLYju4ZAiV/5B979Gu19FHUmgadvIBh7+8iOmn4gRxqVTMVvdnMWhwRpEc2ZFUTm 3SGa2ecpwrgscl+omhYiyf5J1VrWSQ67qZQNmn4oOxP2AdMi5N9ETEd5d5AApUbPS6TV 1qOeO0YTsk6CAPDuRzotnDcuwf38QuqC9XTxorPCFpYfEIBjcmfbMHbGJaAe16pMGCZy Qd9RUuZku/th+Vi/gqud8Y4XvtocSh2YbdRm2HtMMEQM6M+RxIzP/FqQi/+fv7ggdM0M VlnsCs0ZyhQcYqceXgcsIbGWNoBioJZZgyFLyyqlSla5bP+weIM+Skeq9+3hf6tdU++9 WBeA== 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=1Z6HP9drGvNgG/8oTbMRzneYXmIn+6nu8Gn0+Jd30xw=; b=HOtLi7hzMXKLksW5qoxKQe9RZur822dXOCd89KVFGvu0AoYTFX9AJscuWUcQrfIn5P tEmlDDBUHhJmEF9/tgZEXwA31gfrYjrNBVt7k3GhwxAAscaD9+4EGUa+fJY2BX434bbg h/f2ZDe4OY0DmftVgWgEJCCPgcbpxiyWaMJbdQDk0mHlgYGruqDWkCUgs2Dq3RcIt5hc mSf4I6s8FBuOaC4wudjW4bhtVqJbKAOl0wT8kZm/wzMJnNEFAUemhZPWGQJfSM4+kiXu kC8/bBS3yIGIg4WrKZ1GWYGqlSsnET4kyQa2Zqxuj/gq/spOf45w6jEODIOV0grutP7u D3lA== 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 t5si1175837edr.374.2020.04.21.01.54.57; Tue, 21 Apr 2020 01:55:21 -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 S1728055AbgDUIyv (ORCPT + 99 others); Tue, 21 Apr 2020 04:54:51 -0400 Received: from mx2.suse.de ([195.135.220.15]:41504 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726628AbgDUIyu (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 C9B2DAC92; Tue, 21 Apr 2020 08:54:47 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 313F41E0E3B; Tue, 21 Apr 2020 10:54:48 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , , Eric Sandeen , Jan Kara Subject: [PATCH 1/3] fs: Avoid leaving freed inode on dirty list Date: Tue, 21 Apr 2020 10:54:43 +0200 Message-Id: <20200421085445.5731-2-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 evict() can race with writeback_sb_inodes() and so list_empty(&inode->i_io_list) check can race with list_move() from redirty_tail() possibly resulting in list_empty() returning false and thus we end up leaving freed inode in wb->b_dirty list leading to use-after-free issues. Fix the problem by using list_empty_careful() check and add assert that inode's i_io_list is empty in clear_inode() to catch the problem earlier in the future. Signed-off-by: Jan Kara --- fs/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/inode.c b/fs/inode.c index 93d9252a00ab..a73c8a7aa71a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -534,6 +534,7 @@ void clear_inode(struct inode *inode) BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(inode->i_state & I_CLEAR); BUG_ON(!list_empty(&inode->i_wb_list)); + BUG_ON(!list_empty(&inode->i_io_list)); /* don't need i_lock here, no concurrent mods to i_state */ inode->i_state = I_FREEING | I_CLEAR; } @@ -559,7 +560,13 @@ static void evict(struct inode *inode) BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(!list_empty(&inode->i_lru)); - if (!list_empty(&inode->i_io_list)) + /* + * We are the only holder of the inode so it cannot be marked dirty. + * Flusher thread won't start new writeback but there can be still e.g. + * redirty_tail() running from writeback_sb_inodes(). So we have to be + * careful to remove inode from dirty/io list in all the cases. + */ + if (!list_empty_careful(&inode->i_io_list)) inode_io_list_del(inode); inode_sb_list_del(inode); -- 2.16.4