Message ID | 20211108143616.660340-4-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
Series | [PULL,01/10] target-i386: mmu: use pg_mode instead of HF_LMA_MASK | expand |
On 11/8/21 15:36, Paolo Bonzini wrote: > From: Mauro Matteo Cascella <mcascell@redhat.com> > > This avoids an off-by-one read of 'mode_sense_valid' buffer in > hw/scsi/scsi-disk.c:mode_sense_page(). > > Fixes: CVE-2021-3930 > Cc: qemu-stable@nongnu.org > Reported-by: Alexander Bulekov <alxndr@bu.edu> > Fixes: a8f4bbe2900 ("scsi-disk: store valid mode pages in a table") > Fixes: #546 https://gitlab.com/qemu-project/qemu/-/issues/546 > Reported-by: Qiuhao Li <Qiuhao.Li@outlook.com> > Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > hw/scsi/scsi-disk.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c > index e8a547dbb7..d4914178ea 100644 > --- a/hw/scsi/scsi-disk.c > +++ b/hw/scsi/scsi-disk.c > @@ -1087,6 +1087,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, > uint8_t *p = *p_outbuf + 2; > int length; > > + assert(page < ARRAY_SIZE(mode_sense_valid)); > if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) { > return -1; > } > @@ -1428,6 +1429,11 @@ static int scsi_disk_check_mode_select(SCSIDiskState *s, int page, > return -1; > } > > + /* MODE_PAGE_ALLS is only valid for MODE SENSE commands */ > + if (page == MODE_PAGE_ALLS) { > + return -1; > + } > + > p = mode_current; > memset(mode_current, 0, inlen + 2); > len = mode_sense_page(s, page, &p, 0); >
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e8a547dbb7..d4914178ea 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -1087,6 +1087,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, uint8_t *p = *p_outbuf + 2; int length; + assert(page < ARRAY_SIZE(mode_sense_valid)); if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) { return -1; } @@ -1428,6 +1429,11 @@ static int scsi_disk_check_mode_select(SCSIDiskState *s, int page, return -1; } + /* MODE_PAGE_ALLS is only valid for MODE SENSE commands */ + if (page == MODE_PAGE_ALLS) { + return -1; + } + p = mode_current; memset(mode_current, 0, inlen + 2); len = mode_sense_page(s, page, &p, 0);