Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2232240imm; Mon, 28 May 2018 04:25:54 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpA3hZvB1TM6hhw/fTnvT+22TCjPOUKMXYkaEezX34EEfOUKi27O3GGu3sI/VMTsCcJHXjh X-Received: by 2002:a17:902:ab93:: with SMTP id f19-v6mr13518479plr.392.1527506753996; Mon, 28 May 2018 04:25:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527506753; cv=none; d=google.com; s=arc-20160816; b=0TddO6tu8h4NIMc/mJvvzB39ywGjbUlQ3oJ9yPTraoNB2ps+aVYU4c1qChrp0nLeIx 80KymEyMHokwOYdmWt0E/nJLqzCZpOzt+mBQqpLIs+3ZvxXNDPIsRhPdpsEmRzfdJi9K +4cd3bTgbQbwWeAECpSZsUQ8dlO5KnU4OcZDRp21DtZPe7iKFUxuoy2Ns1YAFdXLshMx +IRSaCeSeRppJUXIwC6JKcIlk1JQPnx5hxYAk7enQySZ8wkoU64Vl6Rq7+jB/VfMrnYJ EMJ6hqyw7yTZwzHRudsV2UFoThTYm/6FqHjTTDxBXHzBwaRGK8YXP7aFW++V+v6dG5SA NTqA== 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=d1qKhIZrmHITuQH4n5QJcEHcnVbCVJ6MfbOSLS7kUmA=; b=DzRRFQ9HQ1DCa7eMVXkgNBgezExXr02Nce/FcJ1PHkI3o+5g4322boSQiI4E2StdAS V53eNHTLVYxZ0/UFJasGAdDLENYXcoqAt5aug/Z8ztQErto0oyLWKPA+pSXyg3XwNdYY 034oIXA7JvNeYpdUPjYD4LGnm/AAEUua5vW0V9x0gn+9a1Y9J5gSV9iirzyo8iE/ndr7 NsDAqcZJGgT+KtfnPOhNsmvPtO91Wn+dQI01r+Zv4zsuDnsviwIxtKEOsiC3zy0rZR4c 9WxLttQ/NLKeAiPAViM45mWhN42ceH3f3IBkzEcqX0C/yrePYfRZnvV3NFhnm0JLc8Wu 4h/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=1wXkJhNm; 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 e10-v6si23420552pgo.397.2018.05.28.04.25.39; Mon, 28 May 2018 04:25:53 -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=1wXkJhNm; 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 S1424853AbeE1LYm (ORCPT + 99 others); Mon, 28 May 2018 07:24:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:40702 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1424453AbeE1LYj (ORCPT ); Mon, 28 May 2018 07:24:39 -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 E93F920844; Mon, 28 May 2018 11:24:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527506678; bh=/LspraP9gwyUfLqtYgap0oqY/i4SWVCb74eQVt8teLI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1wXkJhNmccwOsIphFN1dvEsgXuatHgUcGlUY0HHzAT7OXkxB8PxSooKBCH2EYZDFA H/i2WTXLqJHGlOaxrAPh97cD3cS6Ho89MPgInjc8wTqxhddEBn8987puZ2igB4O9wT HeV+A2zX5EO7rltSg4dpVf5KjGLIsfGF3CvG2OPA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Al Viro Subject: [PATCH 4.16 011/272] aio: fix io_destroy(2) vs. lookup_ioctx() race Date: Mon, 28 May 2018 12:00:44 +0200 Message-Id: <20180528100241.222266816@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528100240.256525891@linuxfoundation.org> References: <20180528100240.256525891@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.16-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();