Hide Forgot
An infinite loop vulnerability was found in gem_receive(). Vulnerable code: static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) { ... rxbufsize = ((s->regs[GEM_DMACFG] & GEM_DMACFG_RBUFSZ_M) >> // here set the rxbufsize=0 GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL; bytes_to_copy = size; ... DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size); while (bytes_to_copy) { // the bytes_to_copy never be changed /* Do nothing if receive is not enabled. */ if (!gem_can_receive(nc)) { assert(!first_desc); return -1; } DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize), rx_desc_get_buffer(s->rx_desc)); /* Copy packet data to emulated DMA buffer */ cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc) + rxbuf_offset, rxbuf_ptr, MIN(bytes_to_copy, rxbufsize)); rxbuf_ptr += MIN(bytes_to_copy, rxbufsize); bytes_to_copy -= MIN(bytes_to_copy, rxbufsize); // the bytes_to_copy never change ... /* Descriptor write-back. */ cpu_physical_memory_write(s->rx_desc_addr, (uint8_t *)s->rx_desc, sizeof(s->rx_desc)); /* Next descriptor */ if (rx_desc_get_wrap(s->rx_desc)) { DB_PRINT("wrapping RX descriptor list\n"); s->rx_desc_addr = s->regs[GEM_RXQBASE]; } else { DB_PRINT("incrementing RX descriptor list\n"); s->rx_desc_addr += 8; // provide a lot of rx_desc_addr so let this run correctly } gem_get_rx_desc(s); } ... return size; } By setting rxbufsize to 0 (via setting s->regs[GEM_DMACFG]=0), the while condition bytes_to_copy will never change. Although gem_can_receive() has got check for s->rx_desc, by raising s->rx_desc_addr the statement will be executed everytime, causing an infinite loop.
Acknowledgments: Name: Li Qiang (Qihoo 360 Inc.)
Created attachment 1146825 [details] Crash report
Upstream fix: ------------- -> git.qemu.org/?p=qemu.git;a=commit;h=f265ae8c79ce8c194de481e9def1daa3a80dbb96