mirror of https://github.com/xemu-project/xemu.git
scsi: esp: make cmdbuf big enough for maximum CDB size
While doing DMA read into ESP command buffer 's->cmdbuf', it could write past the 's->cmdbuf' area, if it was transferring more than 16 bytes. Increase the command buffer size to 32, which is maximum when 's->do_cmd' is set, and add a check on 'len' to avoid OOB access. Reported-by: Li Qiang <liqiang6-s@360.cn> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
7f0b6e114a
commit
926cde5f3e
|
@ -248,6 +248,8 @@ static void esp_do_dma(ESPState *s)
|
||||||
len = s->dma_left;
|
len = s->dma_left;
|
||||||
if (s->do_cmd) {
|
if (s->do_cmd) {
|
||||||
trace_esp_do_dma(s->cmdlen, len);
|
trace_esp_do_dma(s->cmdlen, len);
|
||||||
|
assert (s->cmdlen <= sizeof(s->cmdbuf) &&
|
||||||
|
len <= sizeof(s->cmdbuf) - s->cmdlen);
|
||||||
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
|
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +347,7 @@ static void handle_ti(ESPState *s)
|
||||||
s->dma_counter = dmalen;
|
s->dma_counter = dmalen;
|
||||||
|
|
||||||
if (s->do_cmd)
|
if (s->do_cmd)
|
||||||
minlen = (dmalen < 32) ? dmalen : 32;
|
minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
|
||||||
else if (s->ti_size < 0)
|
else if (s->ti_size < 0)
|
||||||
minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
|
minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
|
||||||
else
|
else
|
||||||
|
@ -449,7 +451,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||||
break;
|
break;
|
||||||
case ESP_FIFO:
|
case ESP_FIFO:
|
||||||
if (s->do_cmd) {
|
if (s->do_cmd) {
|
||||||
if (s->cmdlen < TI_BUFSZ) {
|
if (s->cmdlen < ESP_CMDBUF_SZ) {
|
||||||
s->cmdbuf[s->cmdlen++] = val & 0xff;
|
s->cmdbuf[s->cmdlen++] = val & 0xff;
|
||||||
} else {
|
} else {
|
||||||
trace_esp_error_fifo_overrun();
|
trace_esp_error_fifo_overrun();
|
||||||
|
|
|
@ -14,6 +14,7 @@ void esp_init(hwaddr espaddr, int it_shift,
|
||||||
|
|
||||||
#define ESP_REGS 16
|
#define ESP_REGS 16
|
||||||
#define TI_BUFSZ 16
|
#define TI_BUFSZ 16
|
||||||
|
#define ESP_CMDBUF_SZ 32
|
||||||
|
|
||||||
typedef struct ESPState ESPState;
|
typedef struct ESPState ESPState;
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ struct ESPState {
|
||||||
SCSIBus bus;
|
SCSIBus bus;
|
||||||
SCSIDevice *current_dev;
|
SCSIDevice *current_dev;
|
||||||
SCSIRequest *current_req;
|
SCSIRequest *current_req;
|
||||||
uint8_t cmdbuf[TI_BUFSZ];
|
uint8_t cmdbuf[ESP_CMDBUF_SZ];
|
||||||
uint32_t cmdlen;
|
uint32_t cmdlen;
|
||||||
uint32_t do_cmd;
|
uint32_t do_cmd;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue