⬢ DragonFlyBSD Kernel Audit
DF-4941 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ic/if_ic.c	2026-09-25 07:24:38.504972636 +0000
+++ b/sys/dev/netif/ic/if_ic.c	2026-09-25 07:32:42.722704998 +0000
@@ -163,7 +163,6 @@
     struct ifaddr *ifa = (struct ifaddr *)data;
     struct ifreq *ifr = (struct ifreq *)data;
 
-    u_char *iptr, *optr;
     int error;
 
     switch (cmd) {
@@ -202,25 +201,32 @@
 	}
 	break;
 
-    case SIOCSIFMTU:
-	/* save previous buffers */
-	iptr = sc->ic_ifbuf;
-	optr = sc->ic_obuf;
-
-	/* allocate input buffer */
-	sc->ic_ifbuf = kmalloc(ifr->ifr_mtu+ICHDRLEN, M_DEVBUF, M_WAITOK);
+    case SIOCSIFMTU: {
+	char *nifbuf, *nobuf;
 
-	/* allocate output buffer */
-	sc->ic_obuf = kmalloc(ifr->ifr_mtu+ICHDRLEN, M_DEVBUF, M_WAITOK);
+	/* allocate replacement buffers first; never free the working
+	 * pair until both replacements exist (DF-4941) */
+	nifbuf = kmalloc(ifr->ifr_mtu+ICHDRLEN, M_DEVBUF, M_WAITOK|M_NULLOK);
+	nobuf = kmalloc(ifr->ifr_mtu+ICHDRLEN, M_DEVBUF, M_WAITOK|M_NULLOK);
+	if (nifbuf == NULL || nobuf == NULL) {
+	    if (nifbuf)
+		kfree(nifbuf, M_DEVBUF);
+	    if (nobuf)
+		kfree(nobuf, M_DEVBUF);
+	    return (ENOBUFS);
+	}
 
-	if (iptr)
-	    kfree(iptr,M_DEVBUF);
+	if (sc->ic_ifbuf)
+	    kfree(sc->ic_ifbuf, M_DEVBUF);
+	if (sc->ic_obuf)
+	    kfree(sc->ic_obuf, M_DEVBUF);
 
-	if (optr)
-	    kfree(optr,M_DEVBUF);
+	sc->ic_ifbuf = nifbuf;
+	sc->ic_obuf = nobuf;
 
 	sc->ic_if.if_mtu = ifr->ifr_mtu;
 	break;
+    }
 
     case SIOCGIFMTU:
 	ifr->ifr_mtu = sc->ic_if.if_mtu;