Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp5232343ybl; Tue, 27 Aug 2019 01:13:51 -0700 (PDT) X-Google-Smtp-Source: APXvYqwkO4npt8rfU0/Xgwyzpx0jdOX46iwbZksd2uhwjdYLchcVbUXwMxrSdZGJ6p+dA58s8nC7 X-Received: by 2002:a63:1020:: with SMTP id f32mr17106806pgl.203.1566893631144; Tue, 27 Aug 2019 01:13:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566893631; cv=none; d=google.com; s=arc-20160816; b=j3dJwmm9NepX7pHeBx4tiz1tVZX9hpCNw26+CIoQ+KhqqDGUldKgYnwmj3Mxt7HduO o4ydWKoAvU3mb1l1Iot1WkW0crzJqT65FqORVuaSjWrLv8hjqqj+3eRr5Azz0OiFwpds DLxqwSHxeR9otPVIhidwDA/8R3jhzosr0A9zBYsbrDT/HeEvRKwSw95GXFWmcdJYVyo5 KR7nIbZ2YRco0lpVmGptwq9Pea/NwEv3nCR99hPn4PuktGOA7cfYLgeP6MlDKhVR0mrL PxRm9nZaXeD0m+oGvOK+fRgMVlOXWXReAWv9tDB76NZDP3YwMCjPsQmZtOIHeVIn0dIv Q4uw== 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=KFDUrnOI8+gzQdnU9pz9mFtrXygSDTVz98GNYHFjt7A=; b=GAbWJnUiMSJmo4yccanE4qLeEOMNXsQiLctWFU8lQhYZ3Zf2Y8Hoo3SBhlsNfHRa96 pS2P926gBA2lHDyPvVYH3AQFBq+X2KDPbSs5K05JUTh5IFCR8lh+Aa6rR69vPWCOAiiV ggDuvLWhSnyr7L3oNKWOsZ/bvFnDSls3tr/8ijYORjCkTysBN3kRfYfW5VWqwhEP9kcO 3P+hjTTx8gFbBjWWd/w6h9F2Rwwso/rAAKxapZziTuLQkb4yUw58ESqxg/SomTV0leOA IfJuOiP0bo/BK3tJLr6Q0aWWrFTgdLurEzy1G/er2sCJjphY/36JXJeK8+vZUx94rM1b 9H/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="YJv/8O/8"; 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 s3si11268567pgn.467.2019.08.27.01.13.36; Tue, 27 Aug 2019 01:13:51 -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="YJv/8O/8"; 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 S1731861AbfH0ICD (ORCPT + 99 others); Tue, 27 Aug 2019 04:02:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:58294 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726071AbfH0IBr (ORCPT ); Tue, 27 Aug 2019 04:01:47 -0400 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 09792206BF; Tue, 27 Aug 2019 08:01:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1566892906; bh=vVk9Sb/DjoIiqL2j89SBhyyPPoSvb/UenDQ1/pyI9Y0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YJv/8O/8jrJrb1op24iD47NoIWJ+avET5L5adKJu8gc/HUUtD6VBaHAiq7lnE6cAc 6vKqX9IIWHRnoflPan7nZxlGfePsiPD68K9HyQklbiE2/ALSiYtpAbTpUsxgV76ZyP 0JmWHuB07WzUaCTvk6KmvW9uPG1T2xqk1fnVQx/s= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+72af434e4b3417318f84@syzkaller.appspotmail.com, David Howells , Marc Dionne , Jeffrey Altman , Sasha Levin Subject: [PATCH 5.2 053/162] rxrpc: Fix potential deadlock Date: Tue, 27 Aug 2019 09:49:41 +0200 Message-Id: <20190827072740.054489358@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190827072738.093683223@linuxfoundation.org> References: <20190827072738.093683223@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 60034d3d146b11922ab1db613bce062dddc0327a ] There is a potential deadlock in rxrpc_peer_keepalive_dispatch() whereby rxrpc_put_peer() is called with the peer_hash_lock held, but if it reduces the peer's refcount to 0, rxrpc_put_peer() calls __rxrpc_put_peer() - which the tries to take the already held lock. Fix this by providing a version of rxrpc_put_peer() that can be called in situations where the lock is already held. The bug may produce the following lockdep report: ============================================ WARNING: possible recursive locking detected 5.2.0-next-20190718 #41 Not tainted -------------------------------------------- kworker/0:3/21678 is trying to acquire lock: 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: spin_lock_bh /./include/linux/spinlock.h:343 [inline] 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: __rxrpc_put_peer /net/rxrpc/peer_object.c:415 [inline] 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: rxrpc_put_peer+0x2d3/0x6a0 /net/rxrpc/peer_object.c:435 but task is already holding lock: 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: spin_lock_bh /./include/linux/spinlock.h:343 [inline] 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: rxrpc_peer_keepalive_dispatch /net/rxrpc/peer_event.c:378 [inline] 00000000aa5eecdf (&(&rxnet->peer_hash_lock)->rlock){+.-.}, at: rxrpc_peer_keepalive_worker+0x6b3/0xd02 /net/rxrpc/peer_event.c:430 Fixes: 330bdcfadcee ("rxrpc: Fix the keepalive generator [ver #2]") Reported-by: syzbot+72af434e4b3417318f84@syzkaller.appspotmail.com Signed-off-by: David Howells Reviewed-by: Marc Dionne Reviewed-by: Jeffrey Altman Signed-off-by: Sasha Levin --- net/rxrpc/ar-internal.h | 1 + net/rxrpc/peer_event.c | 2 +- net/rxrpc/peer_object.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 80335b4ee4fd6..822f45386e311 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -1061,6 +1061,7 @@ void rxrpc_destroy_all_peers(struct rxrpc_net *); struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *); struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *); void rxrpc_put_peer(struct rxrpc_peer *); +void rxrpc_put_peer_locked(struct rxrpc_peer *); /* * proc.c diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index 9f2f45c09e583..7666ec72d37e5 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c @@ -378,7 +378,7 @@ static void rxrpc_peer_keepalive_dispatch(struct rxrpc_net *rxnet, spin_lock_bh(&rxnet->peer_hash_lock); list_add_tail(&peer->keepalive_link, &rxnet->peer_keepalive[slot & mask]); - rxrpc_put_peer(peer); + rxrpc_put_peer_locked(peer); } spin_unlock_bh(&rxnet->peer_hash_lock); diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c index 9d3ce81cf8ae8..9c3ac96f71cbf 100644 --- a/net/rxrpc/peer_object.c +++ b/net/rxrpc/peer_object.c @@ -436,6 +436,24 @@ void rxrpc_put_peer(struct rxrpc_peer *peer) } } +/* + * Drop a ref on a peer record where the caller already holds the + * peer_hash_lock. + */ +void rxrpc_put_peer_locked(struct rxrpc_peer *peer) +{ + const void *here = __builtin_return_address(0); + int n; + + n = atomic_dec_return(&peer->usage); + trace_rxrpc_peer(peer, rxrpc_peer_put, n, here); + if (n == 0) { + hash_del_rcu(&peer->hash_link); + list_del_init(&peer->keepalive_link); + kfree_rcu(peer, rcu); + } +} + /* * Make sure all peer records have been discarded. */ -- 2.20.1