DragonFlyBSD Kernel Audit
DF-0638 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph7/deflate/ng_deflate.c b/sys/netgraph7/deflate/ng_deflate.c
--- a/sys/netgraph7/deflate/ng_deflate.c
+++ b/sys/netgraph7/deflate/ng_deflate.c
@@ -563,6 +563,15 @@
 	if (proto == PROT_COMPD) {
 		priv->stats.FramesComp++;
 
+		/* DF-0638: inlen must cover the proto + seqnum bytes, otherwise the
+		 * inlen - offset subtraction below underflows into a ~4GiB uInt
+		 * avail_in and inflate() reads out of bounds on the heap. */
+		if (inlen < offset + 2) {
+			priv->stats.Errors++;
+			NG_FREE_M(m);
+			priv->seqnum = 0;
+			return (EPIPE);
+		}
 		/* Check sequence number. */
 		rseqnum = ntohs(((uint16_t *)(priv->inbuf + offset))[0]);
 		offset += 2;
@@ -632,6 +641,13 @@
 	} else { /* Packet is not compressed, just update dictionary. */
 		priv->stats.FramesUncomp++;
 		if (priv->inbuf[0] == 0) {
+		    /* DF-0638: inlen - 1 underflows when inlen == 0 */
+		    if (inlen < 1) {
+			priv->stats.Errors++;
+			NG_FREE_M(m);
+			priv->seqnum = 0;
+			return (EPIPE);
+		    }
 		    priv->cx.next_in = priv->inbuf + 1; /* compress protocol */
 		    priv->cx.avail_in = inlen - 1;
 		} else {