DF-4941 / fix.diff
--- 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; |