Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2233767imm; Mon, 28 May 2018 04:27:44 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI7yG8CKilCvw6+ZljRm7qDH9hIVogZrBv0gHOwEoI4uDfDHdraLE/CXOLE6LHRTxomiXmE X-Received: by 2002:a65:41c6:: with SMTP id b6-v6mr1938683pgq.372.1527506864423; Mon, 28 May 2018 04:27:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527506864; cv=none; d=google.com; s=arc-20160816; b=XvkukbMLnHBc8RlvCdE3i4vMcWUOiRlL3GogBx8PPkvNz3FWru2e1328BpnWfmZWk0 18LhK5PRmqgi0diSEp6p3uUeTqPzg5NIt4Htb2AxtDZQFosShrN8wDus6mAqsH4LAAGl WeNDftNwmIhEVRC2FeKe2kKpK6XxH0W5n2Bz46uSrYJmZlCbyVqeFRXXZrO5tHP1A7ke J/Ng4eD5IvcN044hTSr9ocv3DiUmeIe3SfS/9u4BG54Wkgrv0DSwmWiLwfkfeD2QhYvw djbbyCkSjnvpc9E8VlkwNOi5SAIY+YuQnLcyzi5VshPuRIp9qU6883jtr1vWCzHse8PD f3sg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=NYpbAcdULg+MoyiIgwvEweANbnhidNCN/ft3vC2vQxQ=; b=eVTxW1fr/wQAHq2+EuLzj33EMy/CZpD2dds1fr/7N9TtxtKWWLAf+cEgxFEG3n3m6s XT2qmIqIK5LNjiTyY3K0E7mUSzeCwIc66Vdr/sp7rymO2l6EknkqW51yhvdu6IjVDXop fAJ15XTyCyCaro3KYcrQa0iDhYiwfATaSlOrzQ+UHBlmGrq6DIkISwE6YX+uTN3oR1N/ 3syFghgRvbYtGQvaAetoUErmNWgzYGlYpwOcOblM0woiRKih/YX1+ltXIa/O68f5rVXf Pw2ZSRXDBiSttItc8krnb7XUgIIMgdrlqkvdei3yJDsjTkSS8tXwEq8gW8vHs4outCJI iWGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Ojac/N4o; 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 91-v6si9575660ple.308.2018.05.28.04.27.29; Mon, 28 May 2018 04:27:44 -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=Ojac/N4o; 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 S938142AbeE1LZa (ORCPT + 99 others); Mon, 28 May 2018 07:25:30 -0400 Received: from mail.kernel.org ([198.145.29.99]:41090 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932603AbeE1LZZ (ORCPT ); Mon, 28 May 2018 07:25:25 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (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 89CE920844; Mon, 28 May 2018 11:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527506725; bh=t9VVoRu4LwOePONO5FQitjpQWkCaL90jLoZ9b9aUcs0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ojac/N4oN/ZRZFxaPPIOV74NeThAQFcS3nQnnmef6tOOAIHDfSViyAGtRgXZGlFYf g9RNU794jJ/2+9FvQ4A4p+VWi9Tzy3rlIm7c6g/3002uqNo5F2Za05QbCvLFixDzUo wLyMkEMuwpox5oiuD4uKelYJiYKB+z1ZPdY6y24k= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Al Viro Subject: [PATCH 4.14 007/496] aio: fix io_destroy(2) vs. lookup_ioctx() race Date: Mon, 28 May 2018 11:56:32 +0200 Message-Id: <20180528100319.857219183@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528100319.498712256@linuxfoundation.org> References: <20180528100319.498712256@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Al Viro commit baf10564fbb66ea222cae66fbff11c444590ffd9 upstream. kill_ioctx() used to have an explicit RCU delay between removing the reference from ->ioctx_table and percpu_ref_kill() dropping the refcount. At some point that delay had been removed, on the theory that percpu_ref_kill() itself contained an RCU delay. Unfortunately, that was the wrong kind of RCU delay and it didn't care about rcu_read_lock() used by lookup_ioctx(). As the result, we could get ctx freed right under lookup_ioctx(). Tejun has fixed that in a6d7cff472e ("fs/aio: Add explicit RCU grace period when freeing kioctx"); however, that fix is not enough. Suppose io_destroy() from one thread races with e.g. io_setup() from another; CPU1 removes the reference from current->mm->ioctx_table[...] just as CPU2 has picked it (under rcu_read_lock()). Then CPU1 proceeds to drop the refcount, getting it to 0 and triggering a call of free_ioctx_users(), which proceeds to drop the secondary refcount and once that reaches zero calls free_ioctx_reqs(). That does INIT_RCU_WORK(&ctx->free_rwork, free_ioctx); queue_rcu_work(system_wq, &ctx->free_rwork); and schedules freeing the whole thing after RCU delay. In the meanwhile CPU2 has gotten around to percpu_ref_get(), bumping the refcount from 0 to 1 and returned the reference to io_setup(). Tejun's fix (that queue_rcu_work() in there) guarantees that ctx won't get freed until after percpu_ref_get(). Sure, we'd increment the counter before ctx can be freed. Now we are out of rcu_read_lock() and there's nothing to stop freeing of the whole thing. Unfortunately, CPU2 assumes that since it has grabbed the reference, ctx is *NOT* going away until it gets around to dropping that reference. The fix is obvious - use percpu_ref_tryget_live() and treat failure as miss. It's not costlier than what we currently do in normal case, it's safe to call since freeing *is* delayed and it closes the race window - either lookup_ioctx() comes before percpu_ref_kill() (in which case ctx->users won't reach 0 until the caller of lookup_ioctx() drops it) or lookup_ioctx() fails, ctx->users is unaffected and caller of lookup_ioctx() doesn't see the object in question at all. Cc: stable@kernel.org Fixes: a6d7cff472e "fs/aio: Add explicit RCU grace period when freeing kioctx" Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/aio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- a/fs/aio.c +++ b/fs/aio.c @@ -1087,8 +1087,8 @@ static struct kioctx *lookup_ioctx(unsig ctx = rcu_dereference(table->table[id]); if (ctx && ctx->user_id == ctx_id) { - percpu_ref_get(&ctx->users); - ret = ctx; + if (percpu_ref_tryget_live(&ctx->users)) + ret = ctx; } out: rcu_read_unlock();