Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp266237ybi; Wed, 29 May 2019 21:00:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqwP/yFCzkXwmSOto3i97hMgoEpzcxU+WSiiL+B/2IhGE8NU+D8KO/bmYJGQ+xjOH0RShEzG X-Received: by 2002:a63:de53:: with SMTP id y19mr1823689pgi.166.1559188821364; Wed, 29 May 2019 21:00:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559188821; cv=none; d=google.com; s=arc-20160816; b=Hx8CvxaiZJeKgwFBH0NZiNB6ZOrBWXugz+A2ste4Tujj1E5ZBfMx238/jNWSyriSv8 0IAuc/v8TkB4jnzeoQjDSCmcBf53pxMLN/WAFt3+hSoXHQWd0gNFL9q6zeEgydW+tJ1a 1Ip16xYBvI1Oz2F1pcXMsLoROWKcCfxZXLM+mqFRyKHs4rJJJxog8UNKzbRP/CrlF8Gg 3v13xgWxk410DvoXoHMhp8H5/qdCNdQ80Vm5peVcadQV8BRF02iLg1Q/IzcionUVIKzq ZX1XqTnAcUrJdkgLU7OUIzTo7DiphHnzKOMpvqIuTVpDGIXfrn+3N7i50A2jLqbB0aE6 aFXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=d/Y15UnPncOVTg+vMkp+wJKsAvbmHx30mqehb7f6wyI=; b=qEG/TLFVkEMPWYhMI/6ITtCys9uusBIuZwu9OTfk8F91O2dlQ8yZvSi1RrLp11J+Aq fyAvVZjaa9q4MrGPshglQGbTevvWcLa1p26piPHl3HfKQX5QezedXHN4UJd9f5HjFic4 RN5I3YEZpI1rbxKwDoJXnzomSV0FAz4KCeZPySaHj1DzR1PdyqYssyzR0z5tYkqqEm1p 2ULHuWVDc7BEyEu6YMJ+zQ5l6iW2s9LwX4byqpVTskw8/Vjl5x4pjmRuk4DOI3BtcoMW Dt2/m+Gm6ZBr3SC7/nt2B/dtz4EK17q6x5sVyGg8AiipFyEVpQc45yuo4L5v+JcRWLp/ w18A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nFvRTuS3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i22si2149177pfd.84.2019.05.29.21.00.05; Wed, 29 May 2019 21:00:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nFvRTuS3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387931AbfE3D5y (ORCPT + 99 others); Wed, 29 May 2019 23:57:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:52524 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731698AbfE3DSr (ORCPT ); Wed, 29 May 2019 23:18:47 -0400 Received: from localhost (ip67-88-213-2.z213-88-67.customer.algx.net [67.88.213.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 17BCE247D8; Thu, 30 May 2019 03:18:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186326; bh=g3m7bodQ6vo14Ps6d5WWyAcDcR3EOLYJj6Uq2u3ZAMI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nFvRTuS343x1N3T5IyYl91Gt2gfE0XrZ4Jgxbh8HavEi4HZC+01La4al2howbkMu7 fvXWxw44rrEyTwS/REPZXtfRfXMpWRd6QhOJu4Zs8AekaCrQHgwG/08htP8oMr4KCP iLvJ/kOXyTR16ZkxEAyb8LfCzCN89iFDb+rJ+dq4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ross Lagerwall , Andreas Gruenbacher , Bob Peterson , Sasha Levin Subject: [PATCH 4.14 040/193] gfs2: Fix occasional glock use-after-free Date: Wed, 29 May 2019 20:04:54 -0700 Message-Id: <20190530030455.027656488@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190530030446.953835040@linuxfoundation.org> References: <20190530030446.953835040@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit 9287c6452d2b1f24ea8e84bd3cf6f3c6f267f712 ] This patch has to do with the life cycle of glocks and buffers. When gfs2 metadata or journaled data is queued to be written, a gfs2_bufdata object is assigned to track the buffer, and that is queued to various lists, including the glock's gl_ail_list to indicate it's on the active items list. Once the page associated with the buffer has been written, it is removed from the ail list, but its life isn't over until a revoke has been successfully written. So after the block is written, its bufdata object is moved from the glock's gl_ail_list to a file-system-wide list of pending revokes, sd_log_le_revoke. At that point the glock still needs to track how many revokes it contributed to that list (in gl_revokes) so that things like glock go_sync can ensure all the metadata has been not only written, but also revoked before the glock is granted to a different node. This is to guarantee journal replay doesn't replay the block once the glock has been granted to another node. Ross Lagerwall recently discovered a race in which an inode could be evicted, and its glock freed after its ail list had been synced, but while it still had unwritten revokes on the sd_log_le_revoke list. The evict decremented the glock reference count to zero, which allowed the glock to be freed. After the revoke was written, function revoke_lo_after_commit tried to adjust the glock's gl_revokes counter and clear its GLF_LFLUSH flag, at which time it referenced the freed glock. This patch fixes the problem by incrementing the glock reference count in gfs2_add_revoke when the glock's first bufdata object is moved from the glock to the global revokes list. Later, when the glock's last such bufdata object is freed, the reference count is decremented. This guarantees that whichever process finishes last (the revoke writing or the evict) will properly free the glock, and neither will reference the glock after it has been freed. Reported-by: Ross Lagerwall Signed-off-by: Andreas Gruenbacher Signed-off-by: Bob Peterson Signed-off-by: Sasha Levin --- fs/gfs2/glock.c | 1 + fs/gfs2/log.c | 3 ++- fs/gfs2/lops.c | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index cd6a64478a026..aea1ed0aebd0f 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -140,6 +140,7 @@ void gfs2_glock_free(struct gfs2_glock *gl) { struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + BUG_ON(atomic_read(&gl->gl_revokes)); rhashtable_remove_fast(&gl_hash_table, &gl->gl_node, ht_parms); smp_mb(); wake_up_glock(gl); diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index f72c442314062..483b82e2be923 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -588,7 +588,8 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) bd->bd_bh = NULL; bd->bd_ops = &gfs2_revoke_lops; sdp->sd_log_num_revoke++; - atomic_inc(&gl->gl_revokes); + if (atomic_inc_return(&gl->gl_revokes) == 1) + gfs2_glock_hold(gl); set_bit(GLF_LFLUSH, &gl->gl_flags); list_add(&bd->bd_list, &sdp->sd_log_le_revoke); } diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index c8ff7b7954f05..049f8c6721b4a 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -660,8 +660,10 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) bd = list_entry(head->next, struct gfs2_bufdata, bd_list); list_del_init(&bd->bd_list); gl = bd->bd_gl; - atomic_dec(&gl->gl_revokes); - clear_bit(GLF_LFLUSH, &gl->gl_flags); + if (atomic_dec_return(&gl->gl_revokes) == 0) { + clear_bit(GLF_LFLUSH, &gl->gl_flags); + gfs2_glock_queue_put(gl); + } kmem_cache_free(gfs2_bufdata_cachep, bd); } } -- 2.20.1