From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81941C3F370 for ; Thu, 27 Feb 2020 14:06:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 53F3F2468D for ; Thu, 27 Feb 2020 14:06:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1582812394; bh=IIh3/6eMhrXASqBJV3yaM2anrNKRohA6sfKmGIY7zaU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=WvI6zV5Aiulgsm9tZPOdUXAf+nuW26XADWsQiFzXmckx6wbVkKHOm+vMqrsFlNyFU 3RdE8PcG8S1VyP+2pHnVGOucbKwFit1fyIX/h+WDBD1JrhgcyWwcJhYaQPUQY/8NrI 2dD7J4kENbhNtii2YeYA8kotATC7dNMUUKaZ5f48= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387952AbgB0OGc (ORCPT ); Thu, 27 Feb 2020 09:06:32 -0500 Received: from mail.kernel.org ([198.145.29.99]:43632 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387930AbgB0OG2 (ORCPT ); Thu, 27 Feb 2020 09:06:28 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 4E28520801; Thu, 27 Feb 2020 14:06:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1582812386; bh=IIh3/6eMhrXASqBJV3yaM2anrNKRohA6sfKmGIY7zaU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mrUvsiGsGKPPp6/Us57mq1U9pm8KEwGkzt/DQ7+4d1hn/tUdk3M/mulb3Gc15wIrw hEVvt53f015m8RdSpfNSSwlmUGI/mIMLaWnQEs9nrLN9ogIzuf2aNnBt0NNGhK4iTf ITcORXTZkLWcI//wb4DbtvOgaEPJUgaPVQFbpiwc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+d82f3ac8d87e7ccbb2c9@syzkaller.appspotmail.com, syzbot+3f1fd6b8cbf8702d134e@syzkaller.appspotmail.com, David Howells , Hillf Danton , "David S. Miller" Subject: [PATCH 4.19 94/97] rxrpc: Fix call RCU cleanup using non-bh-safe locks Date: Thu, 27 Feb 2020 14:37:42 +0100 Message-Id: <20200227132230.025826948@linuxfoundation.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200227132214.553656188@linuxfoundation.org> References: <20200227132214.553656188@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 From: David Howells commit 963485d436ccc2810177a7b08af22336ec2af67b upstream. rxrpc_rcu_destroy_call(), which is called as an RCU callback to clean up a put call, calls rxrpc_put_connection() which, deep in its bowels, takes a number of spinlocks in a non-BH-safe way, including rxrpc_conn_id_lock and local->client_conns_lock. RCU callbacks, however, are normally called from softirq context, which can cause lockdep to notice the locking inconsistency. To get lockdep to detect this, it's necessary to have the connection cleaned up on the put at the end of the last of its calls, though normally the clean up is deferred. This can be induced, however, by starting a call on an AF_RXRPC socket and then closing the socket without reading the reply. Fix this by having rxrpc_rcu_destroy_call() punt the destruction to a workqueue if in softirq-mode and defer the destruction to process context. Note that another way to fix this could be to add a bunch of bh-disable annotations to the spinlocks concerned - and there might be more than just those two - but that means spending more time with BHs disabled. Note also that some of these places were covered by bh-disable spinlocks belonging to the rxrpc_transport object, but these got removed without the _bh annotation being retained on the next lock in. Fixes: 999b69f89241 ("rxrpc: Kill the client connection bundle concept") Reported-by: syzbot+d82f3ac8d87e7ccbb2c9@syzkaller.appspotmail.com Reported-by: syzbot+3f1fd6b8cbf8702d134e@syzkaller.appspotmail.com Signed-off-by: David Howells cc: Hillf Danton Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/rxrpc/call_object.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -647,11 +647,11 @@ void rxrpc_put_call(struct rxrpc_call *c } /* - * Final call destruction under RCU. + * Final call destruction - but must be done in process context. */ -static void rxrpc_rcu_destroy_call(struct rcu_head *rcu) +static void rxrpc_destroy_call(struct work_struct *work) { - struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu); + struct rxrpc_call *call = container_of(work, struct rxrpc_call, processor); struct rxrpc_net *rxnet = call->rxnet; rxrpc_put_connection(call->conn); @@ -664,6 +664,22 @@ static void rxrpc_rcu_destroy_call(struc } /* + * Final call destruction under RCU. + */ +static void rxrpc_rcu_destroy_call(struct rcu_head *rcu) +{ + struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu); + + if (in_softirq()) { + INIT_WORK(&call->processor, rxrpc_destroy_call); + if (!rxrpc_queue_work(&call->processor)) + BUG(); + } else { + rxrpc_destroy_call(&call->processor); + } +} + +/* * clean up a call */ void rxrpc_cleanup_call(struct rxrpc_call *call)