Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2231516imm; Mon, 28 May 2018 04:25:05 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoOzO9/8YVmjAjALaxMdo73v8gguBgHGAnZ1WBLalddcrODtovVR3RGx42syOe5fJjsTeaQ X-Received: by 2002:a63:86c8:: with SMTP id x191-v6mr10076452pgd.2.1527506705304; Mon, 28 May 2018 04:25:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527506705; cv=none; d=google.com; s=arc-20160816; b=Gj7Su0oEhO399rQkyXHzdQwDXkb+3YDfe/ovBPb4KPNkgfvJ0EE19Kf3yF+4oBNSir wkXeEBQyD+KC14PnRrfi/9TZtsJYNY3OvZUh3J4BEYOSWxloNYHhlz75lXUBdqffaUAT zNruGMdUkmId4t9uviJrWWvdvWK7uU5OoEm4t4f4jUDNYh0hYi2zJ8DUg+hc6wLP3rpv SLWlZ9E0UxzfNi4wDCrVL4omRzFg4JwSHB6TrPvRZf+lZbifAUZm7vFXvCd+qR+nTaWJ IALutSxOv4oJftUUc3+DlPCN8XVfmXTYN5CFdRBIA+66yYxyi4AYM4glXQQZV80NIWNF emSQ== 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=h5g98cWpjGvufnFwrySnv2AS+g9VJAdsjrbWCLhQ0vw=; b=yPZu64XFJLwojHIVoy1pXBfbBWGwb4pkOno8FlWW4CnkDOCBqZHabT7amXU3tbXrGE hfurVB55mStWZqejGd857xSjP+hPwBLWxJvljqTfEGnEWR1WVq7naWO7QLZmgIAvtjNH rtTCz8+GqwEIH+AhFSxwd2UhgMOw3lw0Rqzgv2X0JFkkOqOn28OHYF8iF4FYthqQL5lh FbC4Q+EGi+fMX52tLTJ3fPEZNi8lientq6uKPr40x4bYWMM/74UvtKQzAh5m/mwQIj3l Ve2uVMd0W/VFESoqM+zFVbMOaiuzLDGOOwIR5RxyQlvfNVnTr77EOjyXzRuwOgAUK5JP 0gbA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=YUf+/EB7; 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 136-v6si5641802pgf.604.2018.05.28.04.24.50; Mon, 28 May 2018 04:25:05 -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=YUf+/EB7; 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 S1424888AbeE1LXS (ORCPT + 99 others); Mon, 28 May 2018 07:23:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:39702 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1424333AbeE1LXM (ORCPT ); Mon, 28 May 2018 07:23:12 -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 C26E920844; Mon, 28 May 2018 11:23:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527506592; bh=CyXioxI/5vg3lz+KTDkbm8HFze/g5qhKOdTiyuLZRro=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YUf+/EB7YW2P80YISyWkw7j02663VPTvtraEECqP9894IvIo/q3465i7x0F2On5Pa /BNbX3GJ8jzpAA0jCXcAApmrQBnyDCboG4FytcTkayi+3FUGG6gZoD17RrMSjvnVsb fhoHnhbD0nfUJuhLxknfifGBk/1gcBPmGGrH6/Bk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Al Viro Subject: [PATCH 4.4 005/268] aio: fix io_destroy(2) vs. lookup_ioctx() race Date: Mon, 28 May 2018 11:59:39 +0200 Message-Id: <20180528100202.690237967@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528100202.045206534@linuxfoundation.org> References: <20180528100202.045206534@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.4-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 @@ -1066,8 +1066,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();