⬢ DragonFlyBSD Kernel Audit
DF-4948 / fix.diff
← back to finding ↓ download raw
diff -ur a/sys/dev/misc/ipmi/ipmi.c b/sys/dev/misc/ipmi/ipmi.c
--- a/sys/dev/misc/ipmi/ipmi.c
+++ b/sys/dev/misc/ipmi/ipmi.c
@@ -446,6 +446,14 @@
 			return (error);
 		}
 		len = kreq->ir_replylen + 1;
+		/*
+		 * ir_replylen is transport-reported (BMC-controlled byte
+		 * count) and must never be trusted past the allocated
+		 * reply buffer (IPMI_MAX_RX for ioctl requests).
+		 */
+		if (kreq->ir_replybuflen != 0 &&
+		    len > kreq->ir_replybuflen + 1)
+			len = kreq->ir_replybuflen + 1;
 		if (recv->msg.data_len < len &&
 		    (cmd == IPMICTL_RECEIVE_MSG
 #ifdef IPMICTL_RECEIVE_MSG_32
diff -ur a/sys/dev/misc/ipmi/ipmi_smic.c b/sys/dev/misc/ipmi/ipmi_smic.c
--- a/sys/dev/misc/ipmi/ipmi_smic.c
+++ b/sys/dev/misc/ipmi/ipmi_smic.c
@@ -338,6 +338,9 @@
 	/* Terminate the transfer. */
 	if (!smic_read_end(sc))
 		return (0);
+	/* i counts every byte the BMC streamed; clamp to the buffer. */
+	if (i > req->ir_replybuflen)
+		i = req->ir_replybuflen;
 	req->ir_replylen = i;
 #ifdef SMIC_DEBUG
 	device_printf(sc->ipmi_dev, "SMIC: READ finished (%d bytes)\n", i);