From patchwork Sun Dec 6 20:25:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B8rn_Mork?= X-Patchwork-Id: 553185 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 33EEA1402D2 for ; Mon, 7 Dec 2015 07:26:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=mork.no header.i=@mork.no header.b=SecVfOm2; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754281AbbLFU0C (ORCPT ); Sun, 6 Dec 2015 15:26:02 -0500 Received: from canardo.mork.no ([148.122.252.1]:36374 "EHLO canardo.mork.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754169AbbLFU0A (ORCPT ); Sun, 6 Dec 2015 15:26:00 -0500 Received: from nemi.mork.no (nemi.mork.no [IPv6:2001:4641:0:2:e8b:fdff:fe08:971]) (authenticated bits=0) by canardo.mork.no (8.14.4/8.14.4) with ESMTP id tB6KPvIm006063 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Sun, 6 Dec 2015 21:25:58 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mork.no; s=a; t=1449433558; bh=tz4UM8mEo8tjqIgC9/9D8rbigBZ2oQwxhgxvexLm+M4=; h=From:To:Cc:Date:Message-Id:From; b=SecVfOm20VL3OP+HOnkn56xfxnLu1OWcFrK38cK1GIdlpnlxvxKCQQfMYT4e1Tchu R9by9pWJJw+lhkTZymGR+srmcnkNjc2wBQFdmH35jL454/b4RtIZ0UWr1pLpJZ9O4q iU88UzVUQbU4NGri98IIoNmRQptAb5pXuXUvqXSkXxtIPWyfwJlKh9RYlSG9Mzq1eu CX5phd/tecDR0dl5s5QqHIbugOu+hPgN+LUoQPMkKyHx+/GiTHB+b72cO4dy8Zsn5h Lba/Aj17Fh+7gpyQxw3EXchH9BEHlfmNUKjFSCGJJlEDJORANnoxsxIYY+87v/XvBg /GIWB0YTupB+A== Received: from bjorn by nemi.mork.no with local (Exim 4.84) (envelope-from ) id 1a5fsb-0001TD-9K; Sun, 06 Dec 2015 21:25:57 +0100 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= To: netdev@vger.kernel.org Cc: linux-usb@vger.kernel.org, =?UTF-8?q?Bj=C3=B8rn=20Mork?= Subject: [PATCH net-next] net: qmi_wwan: should hold RTNL while changing netdev type Date: Sun, 6 Dec 2015 21:25:50 +0100 Message-Id: <1449433550-5616-1-git-send-email-bjorn@mork.no> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.98.7 at canardo X-Virus-Status: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The notifier calls were thrown in as a last-minute fix for an imagined "this device could be part of a bridge" problem. That revealed a certain lack of locking. Not to mention testing... Avoid this splat: RTNL: assertion failed at net/core/dev.c (1639) CPU: 0 PID: 4293 Comm: bash Not tainted 4.4.0-rc3+ #358 Hardware name: LENOVO 2776LEG/2776LEG, BIOS 6EET55WW (3.15 ) 12/19/2011 0000000000000000 ffff8800ad253d60 ffffffff8122f7cf ffff8800ad253d98 ffff8800ad253d88 ffffffff813833ab 0000000000000002 ffff880230f48560 ffff880230a12900 ffff8800ad253da0 ffffffff813833da 0000000000000002 Call Trace: [] dump_stack+0x4b/0x63 [] call_netdevice_notifiers_info+0x3d/0x59 [] call_netdevice_notifiers+0x13/0x15 [] raw_ip_store+0x81/0x193 [qmi_wwan] [] dev_attr_store+0x20/0x22 [] sysfs_kf_write+0x49/0x50 [] kernfs_fop_write+0x10a/0x151 [] __vfs_write+0x26/0xa5 [] ? percpu_down_read+0x53/0x7f [] ? __sb_start_write+0x5f/0xb0 [] ? __sb_start_write+0x5f/0xb0 [] vfs_write+0xa3/0xe7 [] SyS_write+0x50/0x7e [] entry_SYSCALL_64_fastpath+0x12/0x6f Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode") Signed-off-by: Bjørn Mork --- drivers/net/usb/qmi_wwan.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 9cc361b06909..fa9e55435f61 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,7 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co struct usbnet *dev = netdev_priv(to_net_dev(d)); struct qmi_wwan_state *info = (void *)&dev->data; bool enable; - int err; + int ret; if (strtobool(buf, &enable)) return -EINVAL; @@ -101,18 +102,22 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP)) return len; + if (!rtnl_trylock()) + return restart_syscall(); + /* we don't want to modify a running netdev */ if (netif_running(dev->net)) { netdev_err(dev->net, "Cannot change a running device\n"); - return -EBUSY; + ret = -EBUSY; + goto err; } /* let other drivers deny the change */ - err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net); - err = notifier_to_errno(err); - if (err) { + ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net); + ret = notifier_to_errno(ret); + if (ret) { netdev_err(dev->net, "Type change was refused\n"); - return err; + goto err; } if (enable) @@ -121,7 +126,10 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co info->flags &= ~QMI_WWAN_FLAG_RAWIP; qmi_wwan_netdev_setup(dev->net); call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev->net); - return len; + ret = len; +err: + rtnl_unlock(); + return ret; } static DEVICE_ATTR_RW(raw_ip);