Wed Aug 28 06:07:21 2019 UTC ()
in usbnet_detach(), check both that the private pointer has
been allocated and that unp_attached is true before trying
to access anything else.

fixes a detach problem noticed by maxv when, eg, the call
to usbd_set_config_no() fails and attach bails early.


(mrg)
diff -r1.23 -r1.24 src/sys/dev/usb/usbnet.c

cvs diff -r1.23 -r1.24 src/sys/dev/usb/usbnet.c (expand / switch to unified diff)

--- src/sys/dev/usb/usbnet.c 2019/08/23 04:29:28 1.23
+++ src/sys/dev/usb/usbnet.c 2019/08/28 06:07:21 1.24
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $ */ 1/* $NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 Matthew R. Green 4 * Copyright (c) 2019 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * Common code shared between USB network drivers. 32 * Common code shared between USB network drivers.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/kmem.h> 40#include <sys/kmem.h>
41#include <sys/module.h> 41#include <sys/module.h>
42#include <sys/atomic.h> 42#include <sys/atomic.h>
43 43
44#include <dev/usb/usbnet.h> 44#include <dev/usb/usbnet.h>
45#include <dev/usb/usbhist.h> 45#include <dev/usb/usbhist.h>
46 46
47struct usbnet_cdata { 47struct usbnet_cdata {
48 struct usbnet_chain *uncd_tx_chain; 48 struct usbnet_chain *uncd_tx_chain;
49 struct usbnet_chain *uncd_rx_chain; 49 struct usbnet_chain *uncd_rx_chain;
@@ -1447,38 +1447,39 @@ usbnet_attach_ifp(struct usbnet *un, @@ -1447,38 +1447,39 @@ usbnet_attach_ifp(struct usbnet *un,
1447 ifp->if_softc = un; 1447 ifp->if_softc = un;
1448 1448
1449 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev); 1449 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev);
1450 1450
1451 if (!pmf_device_register(un->un_dev, NULL, NULL)) 1451 if (!pmf_device_register(un->un_dev, NULL, NULL))
1452 aprint_error_dev(un->un_dev, "couldn't establish power handler\n"); 1452 aprint_error_dev(un->un_dev, "couldn't establish power handler\n");
1453} 1453}
1454 1454
1455int 1455int
1456usbnet_detach(device_t self, int flags) 1456usbnet_detach(device_t self, int flags)
1457{ 1457{
1458 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1458 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1459 struct usbnet * const un = device_private(self); 1459 struct usbnet * const un = device_private(self);
 1460 struct usbnet_private * const unp = un->un_pri;
 1461
 1462 /* Detached before attached finished, so just bail out. */
 1463 if (unp == NULL || !unp->unp_attached)
 1464 return 0;
 1465
1460 struct ifnet * const ifp = usbnet_ifp(un); 1466 struct ifnet * const ifp = usbnet_ifp(un);
1461 struct mii_data * const mii = usbnet_mii(un); 1467 struct mii_data * const mii = usbnet_mii(un);
1462 struct usbnet_private * const unp = un->un_pri; 
1463 1468
1464 mutex_enter(&unp->unp_lock); 1469 mutex_enter(&unp->unp_lock);
1465 unp->unp_dying = true; 1470 unp->unp_dying = true;
1466 mutex_exit(&unp->unp_lock); 1471 mutex_exit(&unp->unp_lock);
1467 1472
1468 /* Detached before attached finished, so just bail out. */ 
1469 if (!unp->unp_attached) 
1470 return 0; 
1471 
1472 callout_halt(&unp->unp_stat_ch, NULL); 1473 callout_halt(&unp->unp_stat_ch, NULL);
1473 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL); 1474 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL);
1474 1475
1475 if (ifp->if_flags & IFF_RUNNING) { 1476 if (ifp->if_flags & IFF_RUNNING) {
1476 IFNET_LOCK(ifp); 1477 IFNET_LOCK(ifp);
1477 usbnet_stop_ifp(ifp, 1); 1478 usbnet_stop_ifp(ifp, 1);
1478 IFNET_UNLOCK(ifp); 1479 IFNET_UNLOCK(ifp);
1479 } 1480 }
1480 1481
1481 mutex_enter(&unp->unp_lock); 1482 mutex_enter(&unp->unp_lock);
1482 unp->unp_refcnt--; 1483 unp->unp_refcnt--;
1483 while (unp->unp_refcnt > 0) { 1484 while (unp->unp_refcnt > 0) {
1484 /* Wait for processes to go away */ 1485 /* Wait for processes to go away */