Commit ff589551 authored by Prasad J Pandit's avatar Prasad J Pandit Committed by Paolo Bonzini
Browse files

scsi: esp: check TI buffer index before read/write



The 53C9X Fast SCSI Controller(FSC) comes with internal 16-byte
FIFO buffers. One is used to handle commands and other is for
information transfer. Three control variables 'ti_rptr',
'ti_wptr' and 'ti_size' are used to control r/w access to the
information transfer buffer ti_buf[TI_BUFSZ=16]. In that,

'ti_rptr' is used as read index, where read occurs.
'ti_wptr' is a write index, where write would occur.
'ti_size' indicates total bytes to be read from the buffer.

While reading/writing to this buffer, index could exceed its
size. Add check to avoid OOB r/w access.

Reported-by: default avatarHuawei PSIRT <psirt@huawei.com>
Reported-by: default avatarLi Qiang <liqiang6-s@360.cn>
Signed-off-by: default avatarPrasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1465230883-22303-1-git-send-email-ppandit@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 4b3eec91
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -400,19 +400,17 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
    trace_esp_mem_readb(saddr, s->rregs[saddr]);
    switch (saddr) {
    case ESP_FIFO:
        if (s->ti_size > 0) {
            s->ti_size--;
        if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
            /* Data out.  */
                qemu_log_mask(LOG_UNIMP,
                              "esp: PIO data read not implemented\n");
            qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
            s->rregs[ESP_FIFO] = 0;
            } else {
            esp_raise_irq(s);
        } else if (s->ti_rptr < s->ti_wptr) {
            s->ti_size--;
            s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
            }
            esp_raise_irq(s);
        }
        if (s->ti_size == 0) {
        if (s->ti_rptr == s->ti_wptr) {
            s->ti_rptr = 0;
            s->ti_wptr = 0;
        }
@@ -456,7 +454,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
            } else {
                trace_esp_error_fifo_overrun();
            }
        } else if (s->ti_size == TI_BUFSZ - 1) {
        } else if (s->ti_wptr == TI_BUFSZ - 1) {
            trace_esp_error_fifo_overrun();
        } else {
            s->ti_size++;