aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi
diff options
context:
space:
mode:
authorPrasad J Pandit <pjp@fedoraproject.org>2018-10-27 01:13:14 +0530
committerPaolo Bonzini <pbonzini@redhat.com>2018-11-06 21:35:05 +0100
commite58ccf039650065a9442de43c9816f81e88f27f6 (patch)
tree5f5849f8c32a89d97a874594c7c335074ab227a9 /hw/scsi
parent7f135356564bc776083b7ecee81096ab49e670e4 (diff)
lsi53c895a: check message length value is valid
While writing a message in 'lsi_do_msgin', message length value in 'msg_len' could be invalid due to an invalid migration stream. Add an assertion to avoid an out of bounds access, and reject the incoming migration data if it contains an invalid message length. Discovered by Deja vu Security. Reported by Oracle. Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> Message-Id: <20181026194314.18663-1-ppandit@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/scsi')
-rw-r--r--hw/scsi/lsi53c895a.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d1e6534311..3f207f607c 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -861,10 +861,11 @@ static void lsi_do_status(LSIState *s)
static void lsi_do_msgin(LSIState *s)
{
- int len;
+ uint8_t len;
trace_lsi_do_msgin(s->dbc, s->msg_len);
s->sfbr = s->msg[0];
len = s->msg_len;
+ assert(len > 0 && len <= LSI_MAX_MSGIN_LEN);
if (len > s->dbc)
len = s->dbc;
pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len);
@@ -1705,8 +1706,10 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
break;
case 0x58: /* SBDL */
/* Some drivers peek at the data bus during the MSG IN phase. */
- if ((s->sstat1 & PHASE_MASK) == PHASE_MI)
+ if ((s->sstat1 & PHASE_MASK) == PHASE_MI) {
+ assert(s->msg_len > 0);
return s->msg[0];
+ }
ret = 0;
break;
case 0x59: /* SBDL high */
@@ -2103,11 +2106,23 @@ static int lsi_pre_save(void *opaque)
return 0;
}
+static int lsi_post_load(void *opaque, int version_id)
+{
+ LSIState *s = opaque;
+
+ if (s->msg_len < 0 || s->msg_len > LSI_MAX_MSGIN_LEN) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const VMStateDescription vmstate_lsi_scsi = {
.name = "lsiscsi",
.version_id = 0,
.minimum_version_id = 0,
.pre_save = lsi_pre_save,
+ .post_load = lsi_post_load,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(parent_obj, LSIState),