⬢ DragonFlyBSD Kernel Audit
DF-5504 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/u4b/serial/ucycom.c
+++ b/sys/bus/u4b/serial/ucycom.c
@@ -61,6 +61,19 @@
 
 #define	UCYCOM_MAX_IOLEN	(1024 + 2)	/* bytes */
 
+/*
+ * Bound the synchronous control-request timeout used by ucycom_cfg_write()
+ * (via ucom_cfg_do_request): the cfg callbacks run on the per-adapter ucom
+ * taskqueue, close(2) waits synchronously and uninterruptibly behind them
+ * (ucom_queue_command -> usb_proc_mwait, usb_serial.c:671-672), and the USB
+ * hub event thread drains them at unplug (ucom_detach -> usb_proc_drain,
+ * usb_serial.c:394).  With the 1000 ms production timeout a silent or
+ * just-under-timeout evil Earthmate pins each thread ~1.1 s per open()/
+ * tcsetattr; 250 ms bounds the damage while leaving generous margin for a
+ * functional device.
+ */
+#define	UCYCOM_CFG_TIMEOUT	250		/* ms */
+
 #define	UCYCOM_IFACE_INDEX	0
 
 enum {
@@ -436,7 +449,7 @@
 	sc->sc_temp_cfg[4] = cfg;
 
 	err = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
-	    &req, sc->sc_temp_cfg, 0, 1000);
+	    &req, sc->sc_temp_cfg, 0, UCYCOM_CFG_TIMEOUT);
 	if (err) {
 		DPRINTFN(0, "device request failed, err=%s "
 		    "(ignored)\n", usbd_errstr(err));