DF-1249 / fix.diff
diff --git a/sys/dev/netif/dc/if_dc.c b/sys/dev/netif/dc/if_dc.c --- a/sys/dev/netif/dc/if_dc.c +++ b/sys/dev/netif/dc/if_dc.c @@ -2406,7 +2406,7 @@ struct dc_desc *c = NULL; struct mbuf *m = NULL; unsigned char *ptr; - int i, total_len; + int i, total_len, nfrags; u_int32_t rxstat = 0; i = sc->dc_pnic_rx_bug_save; @@ -2414,11 +2414,17 @@ ptr = sc->dc_pnic_rx_buf; bzero(ptr, DC_RXLEN * 5); - /* Copy all the bytes from the bogus buffers. */ + /* Copy all the bytes from the bogus buffers. + * dc_pnic_rx_buf holds at most DC_RXLEN*5 bytes (5 fragments); + * cap the loop so a misbehaving PNIC producing more fragments + * cannot overflow the salvage buffer. */ + nfrags = 0; while (1) { c = &sc->dc_ldata->dc_rx_list[i]; rxstat = c->dc_status; m = sc->dc_cdata.dc_rx_chain[i]; + if (++nfrags > 5) + break; bcopy(mtod(m, char *), ptr, DC_RXLEN); ptr += DC_RXLEN; /* If this is the last buffer, break out. */ |