------------------------------------------------------------------------ *From*: Paolo Bonzini *Subject*: Re: [Qemu-devel] [PATCH] scsi: check buffer length before reading scsi command *Date*: Wed, 1 Jun 2016 15:10:16 +0200 *User-agent*: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 ------------------------------------------------------------------------ On 31/05/2016 19:53, P J P wrote: >/ From: Prasad J Pandit / >/ / >/ The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte/ >/ FIFO buffer. It is used to handle command and data transfer./ >/ Routine get_cmd() in non-DMA mode, uses 'ti_size' to read scsi/ >/ command into a buffer. Add check to validate command length against/ >/ buffer size to avoid any overrun./ >/ / >/ Reported-by: Li Qiang / >/ Signed-off-by: Prasad J Pandit / >/ ---/ >/ hw/scsi/esp.c | 3 +++/ >/ 1 file changed, 3 insertions(+)/ >/ / >/ diff --git a/tools/qemu-xen/hw/scsi/esp.c b/tools/qemu-xen/hw/scsi/esp.c/ >/ index 60c1b28..953027a 100644/ >/ --- a/tools/qemu-xen/hw/scsi/esp.c/ >/ +++ b/tools/qemu-xen/hw/scsi/esp.c/ >/ @@ -98,6 +98,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t / >/ buflen)/ >/ s->dma_memory_read(s->dma_opaque, buf, dmalen);/ >/ } else {/ >/ dmalen = s->ti_size;/ >/ + if (dmalen > TI_BUFSZ) {/ >/ + return 0;/ >/ + }/ >/ memcpy(buf, s->ti_buf, dmalen);/ >/ buf[0] = buf[2] >> 5;/ >/ }/ >/ / In theory this shouldn't happen, but I agree that it is better to be defensive. I'm queuing this patch. At least the following patch is needed to ensure that ti_size always matches ti_rptr/ti_wptr (Hervé, what do you think about it? should I resubmit it formally?). Also, things are more complicated than necessary due to ti_size being used for both DMA and FIFO transfers. diff --git a/tools/qemu-xen/hw/scsi/esp.c b/tools/qemu-xen/hw/scsi/esp.c index c2f6f8f..6407844 100644 --- a/tools/qemu-xen/hw/scsi/esp.c +++ b/tools/qemu-xen/hw/scsi/esp.c @@ -222,7 +222,7 @@ static void write_response(ESPState *s) } else { s->ti_size = 2; s->ti_rptr = 0; - s->ti_wptr = 0; + s->ti_wptr = 2; s->rregs[ESP_RFLAGS] = 2; } esp_raise_irq(s);