From patchwork Mon Oct 12 13:32:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 317642 Delivered-To: patch@linaro.org Received: by 2002:a92:d603:0:0:0:0:0 with SMTP id w3csp4639703ilm; Mon, 12 Oct 2020 06:49:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzrUW0E6VWWe2hRn/eoJmOQ6c/Ss1naDKSSPTdwMTzJhv8L6f0X8t2T8BCAS82YsRUHzn0N X-Received: by 2002:a17:906:340b:: with SMTP id c11mr28204005ejb.213.1602510544709; Mon, 12 Oct 2020 06:49:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1602510544; cv=none; d=google.com; s=arc-20160816; b=k+/6bsLiMXDBXi0Cr2ROCtWGSeWQxEyBlCDSJgeG/z71e2Zl5ezpI6wvFkMMm2rRAe C5HP4WGCF02CHeuw807w6Mc6KN254blRcpm+5P2NxTw2AXPYhq12zLM2dvvevHdHXGWq luuChoMxIoNmSUkd/nuUOHi8S1mkalN1DtoxdCI/pYTsdBz3SP1X4mYSSXdCqOpCY6eI 8v1dEt02Kr/QukTUkehwHRjE/8k6BFc5piK3tKZ7IgADGSxDj44HCrQUVT70G97onuT5 defCniQGk2m5G8hL1ViqR2OggUQI4+SspvqVEeh8hi1afO1aazb57P5kM6+lyPJyDaKf ORKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=m7ec4PhfBnBtoE8Kz9thKdzKWSFACIp3zmqw8fMagBM=; b=I2ykNl11QZYcaw+L5XaGhxirctJvJ0C6kLt664+wjViOMCX8ym91ph0eM6SLBxMvBf PGTTPyueM3jOX7f8vp+maJj3WxZM4+IGpBv1Q87VIhioTIqFWGpMSLXGb9vnAvfi9R8b m/+Z5gYWNSgTwWRwZ1uXOff2ucO+715yEKFL2IHheueAKMjEjILszIvQUzNfaWOjvlb5 4Tp/L6kooqroR521kJZMhAelVUp8Qysx2Mc9fzAgVeK1NsaYxzo2v4cWfHrxwEFBJQjw Uan5umrrWkU5P7LHkosox0/pJpuD8u3zRR3GleTb4AuMeB5i4Mm2z+jn2Q8LELInhhpx vQhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=t4E1XoVF; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a2si11887469edr.352.2020.10.12.06.49.04; Mon, 12 Oct 2020 06:49:04 -0700 (PDT) Received-SPF: pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=t4E1XoVF; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731902AbgJLNtD (ORCPT + 15 others); Mon, 12 Oct 2020 09:49:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:56164 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731984AbgJLNs2 (ORCPT ); Mon, 12 Oct 2020 09:48:28 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (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 CA19220678; Mon, 12 Oct 2020 13:48:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1602510507; bh=IROcsSuG5TsuWNjMrnvrxtHgBEicVFomcBBNZ4ij5hk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t4E1XoVFZaIyexX9O0FmO39Q/JAUNEJJr6AQ9deiKDGAjeb88V9eK/558dnqvA/+s KxqdrDVtUKQUZ0DRWsBqfoar864quwp9U9LrjKQ/mpHTcQeVXkkfUkfm2f9W5Sg2+C Q4bNY+fCPZTO3zxEL6o6WX6yLqmCIyeOPV1IEJ/w= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Manivannan Sadhasivam , "David S. Miller" , syzbot+0f84f6eed90503da72fc@syzkaller.appspotmail.com Subject: [PATCH 5.8 122/124] net: qrtr: ns: Protect radix_tree_deref_slot() using rcu read locks Date: Mon, 12 Oct 2020 15:32:06 +0200 Message-Id: <20201012133152.760309569@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201012133146.834528783@linuxfoundation.org> References: <20201012133146.834528783@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Manivannan Sadhasivam commit a7809ff90ce6c48598d3c4ab54eb599bec1e9c42 upstream. The rcu read locks are needed to avoid potential race condition while dereferencing radix tree from multiple threads. The issue was identified by syzbot. Below is the crash report: ============================= WARNING: suspicious RCU usage 5.7.0-syzkaller #0 Not tainted ----------------------------- include/linux/radix-tree.h:176 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 2 locks held by kworker/u4:1/21: #0: ffff88821b097938 ((wq_completion)qrtr_ns_handler){+.+.}-{0:0}, at: spin_unlock_irq include/linux/spinlock.h:403 [inline] #0: ffff88821b097938 ((wq_completion)qrtr_ns_handler){+.+.}-{0:0}, at: process_one_work+0x6df/0xfd0 kernel/workqueue.c:2241 #1: ffffc90000dd7d80 ((work_completion)(&qrtr_ns.work)){+.+.}-{0:0}, at: process_one_work+0x71e/0xfd0 kernel/workqueue.c:2243 stack backtrace: CPU: 0 PID: 21 Comm: kworker/u4:1 Not tainted 5.7.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: qrtr_ns_handler qrtr_ns_worker Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1e9/0x30e lib/dump_stack.c:118 radix_tree_deref_slot include/linux/radix-tree.h:176 [inline] ctrl_cmd_new_lookup net/qrtr/ns.c:558 [inline] qrtr_ns_worker+0x2aff/0x4500 net/qrtr/ns.c:674 process_one_work+0x76e/0xfd0 kernel/workqueue.c:2268 worker_thread+0xa7f/0x1450 kernel/workqueue.c:2414 kthread+0x353/0x380 kernel/kthread.c:268 Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace") Reported-and-tested-by: syzbot+0f84f6eed90503da72fc@syzkaller.appspotmail.com Signed-off-by: Manivannan Sadhasivam Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/qrtr/ns.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -193,12 +193,13 @@ static int announce_servers(struct socka struct qrtr_server *srv; struct qrtr_node *node; void __rcu **slot; - int ret; + int ret = 0; node = node_get(qrtr_ns.local_node); if (!node) return 0; + rcu_read_lock(); /* Announce the list of servers registered in this node */ radix_tree_for_each_slot(slot, &node->servers, &iter, 0) { srv = radix_tree_deref_slot(slot); @@ -206,11 +207,14 @@ static int announce_servers(struct socka ret = service_announce_new(sq, srv); if (ret < 0) { pr_err("failed to announce new service\n"); - return ret; + goto err_out; } } - return 0; +err_out: + rcu_read_unlock(); + + return ret; } static struct qrtr_server *server_add(unsigned int service, @@ -335,7 +339,7 @@ static int ctrl_cmd_bye(struct sockaddr_ struct qrtr_node *node; void __rcu **slot; struct kvec iv; - int ret; + int ret = 0; iv.iov_base = &pkt; iv.iov_len = sizeof(pkt); @@ -344,11 +348,13 @@ static int ctrl_cmd_bye(struct sockaddr_ if (!node) return 0; + rcu_read_lock(); /* Advertise removal of this client to all servers of remote node */ radix_tree_for_each_slot(slot, &node->servers, &iter, 0) { srv = radix_tree_deref_slot(slot); server_del(node, srv->port); } + rcu_read_unlock(); /* Advertise the removal of this client to all local servers */ local_node = node_get(qrtr_ns.local_node); @@ -359,6 +365,7 @@ static int ctrl_cmd_bye(struct sockaddr_ pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE); pkt.client.node = cpu_to_le32(from->sq_node); + rcu_read_lock(); radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) { srv = radix_tree_deref_slot(slot); @@ -372,11 +379,14 @@ static int ctrl_cmd_bye(struct sockaddr_ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); if (ret < 0) { pr_err("failed to send bye cmd\n"); - return ret; + goto err_out; } } - return 0; +err_out: + rcu_read_unlock(); + + return ret; } static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, @@ -394,7 +404,7 @@ static int ctrl_cmd_del_client(struct so struct list_head *li; void __rcu **slot; struct kvec iv; - int ret; + int ret = 0; iv.iov_base = &pkt; iv.iov_len = sizeof(pkt); @@ -434,6 +444,7 @@ static int ctrl_cmd_del_client(struct so pkt.client.node = cpu_to_le32(node_id); pkt.client.port = cpu_to_le32(port); + rcu_read_lock(); radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) { srv = radix_tree_deref_slot(slot); @@ -447,11 +458,14 @@ static int ctrl_cmd_del_client(struct so ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); if (ret < 0) { pr_err("failed to send del client cmd\n"); - return ret; + goto err_out; } } - return 0; +err_out: + rcu_read_unlock(); + + return ret; } static int ctrl_cmd_new_server(struct sockaddr_qrtr *from, @@ -554,6 +568,7 @@ static int ctrl_cmd_new_lookup(struct so filter.service = service; filter.instance = instance; + rcu_read_lock(); radix_tree_for_each_slot(node_slot, &nodes, &node_iter, 0) { node = radix_tree_deref_slot(node_slot); @@ -568,6 +583,7 @@ static int ctrl_cmd_new_lookup(struct so lookup_notify(from, srv, true); } } + rcu_read_unlock(); /* Empty notification, to indicate end of listing */ lookup_notify(from, NULL, true);