DragonFlyBSD Kernel Audit
DF-1499 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/misc/musycc/musycc.c b/sys/dev/misc/musycc/musycc.c
--- a/sys/dev/misc/musycc/musycc.c
+++ b/sys/dev/misc/musycc/musycc.c
@@ -441,35 +441,39 @@
  */
 
 static void
-status_chans(struct softc *sc, char *s)
+status_chans(struct softc *sc, char *s, size_t cap)
 {
 	int i;
 	struct schan *scp;
+	size_t used = strlen(s);
 
-	s += strlen(s);
 	for (i = 0; i < NHDLC; i++) {
 		scp = sc->chan[i];
 		if (scp == NULL)
 			continue;
-		ksprintf(s + strlen(s), "c%2d:", i);
-		ksprintf(s + strlen(s), " ts %08x", scp->ts);
-		ksprintf(s + strlen(s), " RX %lus/%lus",
-		    time_uptime - scp->last_recv, time_uptime - scp->last_rxerr);
-		ksprintf(s + strlen(s), " TX %lus/%lus/%lus",
-		    time_uptime - scp->last_xmit,
-		    time_uptime - scp->last_txerr,
-		    time_uptime - scp->last_txdrop);
-		ksprintf(s + strlen(s), " TXdrop %lu Pend %lu",
-		    scp->tx_drop,
-		    scp->tx_pending);
-		ksprintf(s + strlen(s), " CRC %lu Dribble %lu Long %lu Short %lu Abort %lu",
-		    scp->crc_error,
-		    scp->dribble_error,
-		    scp->long_error,
-		    scp->short_error,
-		    scp->abort_error);
-		ksprintf(s + strlen(s), "\n TX: %lu RX: %lu\n",
+		/*
+		 * DF-1499: each channel emits ~140-360 bytes via ksprintf;
+		 * with NHDLC=32 channels open, the unbounded version overruns
+		 * the NG_TEXTRESPONSE(1024)-byte response buffer by several KB.
+		 * Bound each emit against the remaining capacity and stop
+		 * appending once the buffer is full.
+		 */
+		int n = ksnprintf(s + used, cap - used,
+		    "c%2d: ts %08x RX %lus/%lus TX %lus/%lus/%lus "
+		    "TXdrop %lu Pend %lu "
+		    "CRC %lu Dribble %lu Long %lu Short %lu Abort %lu "
+		    "\n TX: %lu RX: %lu\n",
+		    i, scp->ts,
+		    time_uptime - scp->last_recv, time_uptime - scp->last_rxerr,
+		    time_uptime - scp->last_xmit, time_uptime - scp->last_txerr,
+		    time_uptime - scp->last_txdrop,
+		    scp->tx_drop, scp->tx_pending,
+		    scp->crc_error, scp->dribble_error, scp->long_error,
+		    scp->short_error, scp->abort_error,
 		    scp->txn, scp->rxn);
+		if (n < 0 || (size_t)n >= cap - used)
+			break;		/* out of room */
+		used += (size_t)n;
 	}
 }
 
@@ -1005,7 +1009,7 @@
 		}
 		s = (char *)(*resp)->data;
 		status_8370(sc, s);
-		status_chans(sc,s);
+		status_chans(sc, s, NG_TEXTRESPONSE);
 		(*resp)->header.arglen = strlen(s) + 1;
 		kfree(msg, M_NETGRAPH);
 		return (0);