]>
Commit | Line | Data |
---|---|---|
430fd895 TL |
1 | From 0988f56451a246d5b72484e0c6dd37fe1bd69d12 Mon Sep 17 00:00:00 2001 |
2 | From: Prasad J Pandit <pjp@fedoraproject.org> | |
3 | Date: Thu, 16 Jun 2016 00:22:35 +0200 | |
4 | Subject: [PATCH 1/2] scsi: esp: make cmdbuf big enough for maximum CDB size | |
5 | ||
6 | While doing DMA read into ESP command buffer 's->cmdbuf', it could | |
7 | write past the 's->cmdbuf' area, if it was transferring more than 16 | |
8 | bytes. Increase the command buffer size to 32, which is maximum when | |
9 | 's->do_cmd' is set, and add a check on 'len' to avoid OOB access. | |
10 | ||
11 | Reported-by: Li Qiang <liqiang6-s@360.cn> | |
12 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | |
13 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
14 | ||
15 | Conflicts: | |
16 | hw/scsi/esp.c | |
17 | commit ff589551c8e8e9e95e211b9d8daafb4ed39f1aec | |
18 | scsi: esp: check TI buffer index before read/write | |
19 | ||
20 | added additional control variables to ESPState as ti_size | |
21 | wasn't enough, we thus ran in a conflict here, use only | |
22 | ti_size for now as conflict resolution. | |
23 | ||
24 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
25 | --- | |
26 | hw/scsi/esp.c | 10 ++++++++-- | |
27 | include/hw/scsi/esp.h | 3 ++- | |
28 | 2 files changed, 10 insertions(+), 3 deletions(-) | |
29 | ||
30 | diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c | |
31 | index 8961be2..e533522 100644 | |
32 | --- a/hw/scsi/esp.c | |
33 | +++ b/hw/scsi/esp.c | |
34 | @@ -243,6 +243,8 @@ static void esp_do_dma(ESPState *s) | |
35 | len = s->dma_left; | |
36 | if (s->do_cmd) { | |
37 | trace_esp_do_dma(s->cmdlen, len); | |
38 | + assert (s->cmdlen <= sizeof(s->cmdbuf) && | |
39 | + len <= sizeof(s->cmdbuf) - s->cmdlen); | |
40 | s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); | |
41 | s->ti_size = 0; | |
42 | s->cmdlen = 0; | |
43 | @@ -342,7 +344,7 @@ static void handle_ti(ESPState *s) | |
44 | s->dma_counter = dmalen; | |
45 | ||
46 | if (s->do_cmd) | |
47 | - minlen = (dmalen < 32) ? dmalen : 32; | |
48 | + minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ; | |
49 | else if (s->ti_size < 0) | |
50 | minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size; | |
51 | else | |
52 | @@ -448,7 +450,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) | |
53 | break; | |
54 | case ESP_FIFO: | |
55 | if (s->do_cmd) { | |
56 | - s->cmdbuf[s->cmdlen++] = val & 0xff; | |
57 | + if (s->cmdlen < ESP_CMDBUF_SZ) { | |
58 | + s->cmdbuf[s->cmdlen++] = val & 0xff; | |
59 | + } else { | |
60 | + trace_esp_error_fifo_overrun(); | |
61 | + } | |
62 | } else if (s->ti_size == TI_BUFSZ - 1) { | |
63 | trace_esp_error_fifo_overrun(); | |
64 | } else { | |
65 | diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h | |
66 | index 6c79527..d2c4886 100644 | |
67 | --- a/include/hw/scsi/esp.h | |
68 | +++ b/include/hw/scsi/esp.h | |
69 | @@ -14,6 +14,7 @@ void esp_init(hwaddr espaddr, int it_shift, | |
70 | ||
71 | #define ESP_REGS 16 | |
72 | #define TI_BUFSZ 16 | |
73 | +#define ESP_CMDBUF_SZ 32 | |
74 | ||
75 | typedef struct ESPState ESPState; | |
76 | ||
77 | @@ -31,7 +32,7 @@ struct ESPState { | |
78 | SCSIBus bus; | |
79 | SCSIDevice *current_dev; | |
80 | SCSIRequest *current_req; | |
81 | - uint8_t cmdbuf[TI_BUFSZ]; | |
82 | + uint8_t cmdbuf[ESP_CMDBUF_SZ]; | |
83 | uint32_t cmdlen; | |
84 | uint32_t do_cmd; | |
85 | ||
86 | -- | |
87 | 2.1.4 | |
88 |