Module Name:    src
Committed By:   maxv
Date:           Sat Sep 14 12:40:31 UTC 2019

Modified Files:
        src/sys/dev/usb: if_urtw.c if_urtwreg.h

Log Message:
Fix error handling, to prevent kernel crashes when detaching an urtw0
device. Also, fail safely if we didn't recognize the RF chip, to prevent
kernel crashes at attach time. Note that other panics are there, maybe
they also should be removed.

Found with vHCI.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/usb/if_urtw.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/usb/if_urtwreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/if_urtw.c
diff -u src/sys/dev/usb/if_urtw.c:1.18 src/sys/dev/usb/if_urtw.c:1.19
--- src/sys/dev/usb/if_urtw.c:1.18	Wed Sep 12 21:57:18 2018
+++ src/sys/dev/usb/if_urtw.c	Sat Sep 14 12:40:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_urtw.c,v 1.18 2018/09/12 21:57:18 christos Exp $	*/
+/*	$NetBSD: if_urtw.c,v 1.19 2019/09/14 12:40:31 maxv Exp $	*/
 /*	$OpenBSD: if_urtw.c,v 1.39 2011/07/03 15:47:17 matthew Exp $	*/
 
 /*-
@@ -19,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.18 2018/09/12 21:57:18 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.19 2019/09/14 12:40:31 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -614,6 +614,7 @@ urtw_attach(device_t parent, device_t se
 	sc->sc_dev = self;
 	sc->sc_udev = uaa->uaa_device;
 	sc->sc_hwrev = urtw_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev;
+	sc->sc_init_state = URTW_INIT_NONE;
 
 	aprint_naive("\n");
 	aprint_normal(": ");
@@ -757,6 +758,8 @@ urtw_attach(device_t parent, device_t se
 
 	ieee80211_announce(ic);
 
+	sc->sc_init_state = URTW_INIT_INITED;
+
 	return;
 fail:
 	aprint_error(": %s failed!\n", __func__);
@@ -774,6 +777,9 @@ urtw_detach(device_t self, int flags)
 
 	sc->sc_dying = true;
 
+	if (sc->sc_init_state < URTW_INIT_INITED)
+		goto out;
+
 	callout_halt(&sc->scan_to, NULL);
 	callout_halt(&sc->sc_led_ch, NULL);
 	callout_destroy(&sc->scan_to);
@@ -794,8 +800,8 @@ urtw_detach(device_t self, int flags)
 	urtw_free_rx_data_list(sc);
 	urtw_close_pipes(sc);
 
+out:
 	splx(s);
-
 	return 0;
 }
 
@@ -1279,8 +1285,7 @@ urtw_get_rfchip(struct urtw_softc *sc)
 	if (sc->sc_hwrev & URTW_HWREV_8187) {
 		error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
 		if (error != 0)
-			panic("unsupported RF chip");
-			/* NOTREACHED */
+			return error;
 		switch (data & 0xff) {
 		case URTW_EPROM_RFCHIPID_RTL8225U:
 			error = urtw_8225_isv2(sc, &ret);
@@ -1313,8 +1318,8 @@ urtw_get_rfchip(struct urtw_softc *sc)
 	return 0;
 
 fail:
-	panic("unsupported RF chip %d", data & 0xff);
-	/* NOTREACHED */
+	aprint_error(": unsupported RF chip %d", data & 0xff);
+	return USBD_INVAL;
 }
 
 usbd_status

Index: src/sys/dev/usb/if_urtwreg.h
diff -u src/sys/dev/usb/if_urtwreg.h:1.2 src/sys/dev/usb/if_urtwreg.h:1.3
--- src/sys/dev/usb/if_urtwreg.h:1.2	Sat Apr 23 10:15:32 2016
+++ src/sys/dev/usb/if_urtwreg.h	Sat Sep 14 12:40:31 2019
@@ -323,6 +323,11 @@ struct urtw_softc {
 	struct ieee80211com		sc_ic;
 	struct ethercom			sc_ec;
 #define sc_if	sc_ec.ec_if
+
+	enum {
+		URTW_INIT_NONE,
+		URTW_INIT_INITED
+	} sc_init_state;
 	int				(*sc_newstate)(struct ieee80211com *,
 					    enum ieee80211_state, int);
 	struct urtw_rf			sc_rf;

Reply via email to