From patchwork Tue Aug 8 10:35:06 2017 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: 799097 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=mork.no header.i=@mork.no header.b="onM77wZ8"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xRW4w2Dg0z9s5L for ; Tue, 8 Aug 2017 20:35:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752082AbdHHKfZ (ORCPT ); Tue, 8 Aug 2017 06:35:25 -0400 Received: from canardo.mork.no ([148.122.252.1]:35001 "EHLO canardo.mork.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751921AbdHHKfY (ORCPT ); Tue, 8 Aug 2017 06:35:24 -0400 Received: from miraculix.mork.no ([IPv6:2a02:2121:30e:a501:2094:80ff:fe3c:6a18]) (authenticated bits=0) by canardo.mork.no (8.15.2/8.15.2) with ESMTPSA id v78AZCIA000427 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 8 Aug 2017 12:35:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mork.no; s=b; t=1502188521; bh=lu1Eq7sf6ISzyg1cLgG6OVxnt0lRiR2HY1TmqEnT354=; h=From:To:Cc:Subject:References:Date:Message-ID:From; b=onM77wZ8rrLSNNG/cVGgEUYEybZJYGvkdYr6A+r3VfwEqLSriPFG4Q1t+kFrOmGw6 a+FSp0ky+1+mxp1bW7nXjN7C+pvb7SP+zx+UwLWhVj5ZCZW2mUzO3AREXO7NuDsTL+ HISVsWKXDku42gtZ1jqLT1WP+bYp0RKy1QspPVks= Received: from bjorn by miraculix.mork.no with local (Exim 4.89) (envelope-from ) id 1df1qs-0000V7-J8; Tue, 08 Aug 2017 12:35:06 +0200 From: =?utf-8?Q?Bj=C3=B8rn_Mork?= To: Nathaniel Roach Cc: netdev@vger.kernel.org, Daniele Palmas Subject: Re: qmi_wwan: Null pointer dereference when removing driver Organization: m References: <0d39998a-dfa9-48c5-0c7f-19354f16a7c0@gmail.com> Date: Tue, 08 Aug 2017 12:35:06 +0200 In-Reply-To: <0d39998a-dfa9-48c5-0c7f-19354f16a7c0@gmail.com> (Nathaniel Roach's message of "Thu, 27 Jul 2017 13:31:00 +0800") Message-ID: <87d1861h5x.fsf@miraculix.mork.no> User-Agent: Gnus/5.130015 (Ma Gnus v0.15) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.99.2 at canardo X-Virus-Status: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Nathaniel Roach writes: > Unsure at which point was added, but issue not present in stock debian 4.11 kernel. > > Running on a Thinkpad X220 with coreboot. > > I'm building from upstream. When I attempt to remove the qmi_wwan module (which also happens pre-suspend) the rmmod process gets killed, and the following shows in dmesg: > > [ 59.979791] usb 2-1.4: USB disconnect, device number 4 > [ 59.980102] qmi_wwan 2-1.4:1.6 wwp0s29u1u4i6: unregister 'qmi_wwan' usb-0000:00:1d.0-1.4, WWAN/QMI device > [ 60.006821] BUG: unable to handle kernel NULL pointer dereference at 00000000000000e0 > [ 60.006879] IP: qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan] > [ 60.006911] PGD 0 > [ 60.006911] P4D 0 > [ 60.006957] Oops: 0000 [#1] SMP > [ 60.006978] Modules linked in: fuse(E) ccm(E) rfcomm(E) cmac(E) bnep(E) qmi_wwan(E) cdc_wdm(E) cdc_ether(E) usbnet(E) mii(E) btusb(E) btrtl(E) btbcm(E) btintel(E) bluetooth(E) joydev(E) xpad(E) ecdh_generic(E) ff_memless(E) binfmt_misc(E) snd_hda_codec_hdmi(E) snd_hda_codec_conexant(E) snd_hda_codec_generic(E) arc4(E) iTCO_wdt(E) iTCO_vendor_support(E) intel_rapl(E) x86_pkg_temp_thermal(E) kvm_intel(E) kvm(E) irqbypass(E) crct10dif_pclmul(E) crc32_pclmul(E) crc32c_intel(E) ghash_clmulni_intel(E) aesni_intel(E) iwlmvm(E) aes_x86_64(E) crypto_simd(E) mac80211(E) cryptd(E) glue_helper(E) snd_hda_intel(E) snd_hda_codec(E) iwlwifi(E) snd_hwdep(E) psmouse(E) snd_hda_core(E) snd_pcm(E) serio_raw(E) sdhci_pci(E) pcspkr(E) snd_timer(E) ehci_pci(E) e1000e(E) i2c_i801(E) ehci_hcd(E) snd(E) sg(E) i915(E) lpc_ich(E) > [ 60.007366] ptp(E) usbcore(E) cfg80211(E) mfd_core(E) pps_core(E) shpchp(E) ac(E) battery(E) tpm_tis(E) tpm_tis_core(E) evdev(E) tpm(E) parport_pc(E) ppdev(E) lp(E) parport(E) ip_tables(E) x_tables(E) autofs4(E) > [ 60.007474] CPU: 2 PID: 33 Comm: kworker/2:1 Tainted: G E 4.12.3-nr44-normandy-r1500619820+ #1 > [ 60.007524] Hardware name: LENOVO 4291LR7/4291LR7, BIOS CBET4000 4.6-810-g50522254fb 07/21/2017 > [ 60.007580] Workqueue: usb_hub_wq hub_event [usbcore] > [ 60.007609] task: ffff8c882b716040 task.stack: ffffb8e800d84000 > [ 60.007644] RIP: 0010:qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan] > [ 60.007678] RSP: 0018:ffffb8e800d87b38 EFLAGS: 00010246 > [ 60.007711] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 > [ 60.007752] RDX: 0000000000000001 RSI: ffff8c8824f3f1d0 RDI: ffff8c8824ef6400 > [ 60.007792] RBP: ffff8c8824ef6400 R08: 0000000000000000 R09: 0000000000000000 > [ 60.007833] R10: ffffb8e800d87780 R11: 0000000000000011 R12: ffffffffc07ea0e8 > [ 60.007874] R13: ffff8c8824e2e000 R14: ffff8c8824e2e098 R15: 0000000000000000 > [ 60.007915] FS: 0000000000000000(0000) GS:ffff8c8835300000(0000) knlGS:0000000000000000 > [ 60.007960] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 60.007994] CR2: 00000000000000e0 CR3: 0000000229ca5000 CR4: 00000000000406e0 > [ 60.008035] Call Trace: > [ 60.008065] ? usb_unbind_interface+0x71/0x270 [usbcore] > [ 60.008101] ? device_release_driver_internal+0x154/0x210 > [ 60.008135] ? qmi_wwan_unbind+0x6d/0xc0 [qmi_wwan] > [ 60.008168] ? usbnet_disconnect+0x6c/0xf0 [usbnet] > [ 60.008194] ? qmi_wwan_disconnect+0x87/0xc0 [qmi_wwan] > [ 60.008232] ? usb_unbind_interface+0x71/0x270 [usbcore] > [ 60.008264] ? device_release_driver_internal+0x154/0x210 > [ 60.008296] ? bus_remove_device+0xf5/0x160 > [ 60.008324] ? device_del+0x1dc/0x310 > [ 60.008355] ? usb_remove_ep_devs+0x1b/0x30 [usbcore] > [ 60.008393] ? usb_disable_device+0x93/0x250 [usbcore] > [ 60.008430] ? usb_disconnect+0x90/0x260 [usbcore] > [ 60.008468] ? hub_event+0x1d9/0x14a0 [usbcore] > [ 60.008500] ? process_one_work+0x175/0x370 > [ 60.008528] ? worker_thread+0x4a/0x380 > [ 60.008555] ? kthread+0xfc/0x130 > [ 60.008579] ? process_one_work+0x370/0x370 > [ 60.008606] ? kthread_park+0x60/0x60 > [ 60.008631] ? ret_from_fork+0x22/0x30 > [ 60.008656] Code: 66 0f 1f 44 00 00 66 66 66 66 90 55 48 89 fd 53 48 83 ec 10 48 8b 9f c8 00 00 00 65 48 8b 04 25 28 00 00 00 48 89 44 24 08 31 c0 83 e0 00 00 00 02 74 51 e8 0d b3 2b cd 85 c0 74 67 48 8b bb > [ 60.011925] RIP: qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan] RSP: ffffb8e800d87b38 > [ 60.013564] CR2: 00000000000000e0 > [ 60.022125] ---[ end trace e536b59f45bc0f25 ]--- > [ 60.025385] IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready > > If I attempt a second rmmod, the process hangs. If I attempt it on 4.11.x it works as expected: > > [ 16.897783] fuse init (API version 7.26) > [ 68.073552] usbcore: deregistering interface driver qmi_wwan > [ 68.075808] qmi_wwan 2-1.4:1.6 wwp0s29u1u4i6: unregister 'qmi_wwan' usb-0000:00:1d.0-1.4, WWAN/QMI device > [ 72.431403] e1000e: enp0s25 NIC Link is Down > > So I'm pretty certain it's not coreboot causing the issue. Thanks a lot for the report! Just one question: Does your modem have separate control and data interfaces? If so, then I believe the attached patch will fix the issue. Are you able to test it? If the modem use the more common cobined interface model. then I need to investigate this further.. Bjørn From c6ca53a5aaf6ce6a2733f75363119444adbe5d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 8 Aug 2017 12:17:25 +0200 Subject: [RFT] qmi_wwan: fix NULL deref on disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qmi_wwan_disconnect is called twice when disconnecting devices with separate control and data interfaces. The first invocation will set the interface data to NULL to flag that disconnect has been handled. But the matching NULL check was left out when qmi_wwan_disconnect was added, resulting in this oops: usb 2-1.4: USB disconnect, device number 4 qmi_wwan 2-1.4:1.6 wwp0s29u1u4i6: unregister 'qmi_wwan' usb-0000:00:1d.0-1.4, WWAN/QMI device BUG: unable to handle kernel NULL pointer dereference at 00000000000000e0 IP: qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan] PGD 0 P4D 0 Oops: 0000 [#1] SMP Modules linked in: CPU: 2 PID: 33 Comm: kworker/2:1 Tainted: G E 4.12.3-nr44-normandy-r1500619820+ #1 Hardware name: LENOVO 4291LR7/4291LR7, BIOS CBET4000 4.6-810-g50522254fb 07/21/2017 Workqueue: usb_hub_wq hub_event [usbcore] task: ffff8c882b716040 task.stack: ffffb8e800d84000 RIP: 0010:qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan] RSP: 0018:ffffb8e800d87b38 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffff8c8824f3f1d0 RDI: ffff8c8824ef6400 RBP: ffff8c8824ef6400 R08: 0000000000000000 R09: 0000000000000000 R10: ffffb8e800d87780 R11: 0000000000000011 R12: ffffffffc07ea0e8 R13: ffff8c8824e2e000 R14: ffff8c8824e2e098 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8c8835300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000e0 CR3: 0000000229ca5000 CR4: 00000000000406e0 Call Trace: ? usb_unbind_interface+0x71/0x270 [usbcore] ? device_release_driver_internal+0x154/0x210 ? qmi_wwan_unbind+0x6d/0xc0 [qmi_wwan] ? usbnet_disconnect+0x6c/0xf0 [usbnet] ? qmi_wwan_disconnect+0x87/0xc0 [qmi_wwan] ? usb_unbind_interface+0x71/0x270 [usbcore] ? device_release_driver_internal+0x154/0x210 Reported-by: Nathaniel Roach Fixes: c6adf77953bc ("net: usb: qmi_wwan: add qmap mux protocol support") Cc: Daniele Palmas Signed-off-by: Bjørn Mork --- drivers/net/usb/qmi_wwan.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index ff6f39fe6c00..8c3733608271 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1341,10 +1341,14 @@ static int qmi_wwan_probe(struct usb_interface *intf, static void qmi_wwan_disconnect(struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - struct qmi_wwan_state *info = (void *)&dev->data; + struct qmi_wwan_state *info; struct list_head *iter; struct net_device *ldev; + /* called twice if separate control and data intf */ + if (!dev) + return; + info = (void *)&dev->data; if (info->flags & QMI_WWAN_FLAG_MUX) { if (!rtnl_trylock()) { restart_syscall(); -- 2.11.0