DF-1795 / fix.diff
diff --git a/sys/dev/netif/plip/if_plip.c b/sys/dev/netif/plip/if_plip.c --- a/sys/dev/netif/plip/if_plip.c +++ b/sys/dev/netif/plip/if_plip.c @@ -346,11 +346,20 @@ break; case SIOCSIFMTU: + { + u_char *newbuf; ptr = sc->sc_ifbuf; - sc->sc_ifbuf = kmalloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_WAITOK); + newbuf = kmalloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_WAITOK); + /* Publish the new buffer and the new mtu together; free the old + * buffer last. Previously the three steps (kmalloc new, kfree old, + * set if_mtu) were unlocked and visible to lp_intr in intermediate + * states, so the interrupt handler could sample the OLD mtu as a + * length bound against the NEW (smaller) buffer and overflow it. */ + sc->sc_ifbuf = newbuf; + sc->sc_if.if_mtu = ifr->ifr_mtu; if (ptr) kfree(ptr,M_DEVBUF); - sc->sc_if.if_mtu = ifr->ifr_mtu; + } break; case SIOCGIFMTU: |