Message ID | 4b15b728-bdfe-3bbe-3a5c-ca3baeef3c5c@siemens.com |
---|---|
State | New |
Headers | show |
Series | hw/i386/intel_iommu: Fix out-of-bounds access on guest IRT | expand |
On 10/03/20 18:42, Jan Kiszka wrote: > From: Jan Kiszka <jan.kiszka@siemens.com> > > vtd_irte_get failed to check the index against the configured table > size, causing an out-of-bounds access on guest memory and potentially > misinterpreting the result. > > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > --- > > BTW, we still miss error reporting emulation, right? Therefore, I added > that simple error_report_once thing, like the other paths do. > > hw/i386/intel_iommu.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c > index 204b6841ec..df7ad254ac 100644 > --- a/hw/i386/intel_iommu.c > +++ b/hw/i386/intel_iommu.c > @@ -3094,6 +3094,12 @@ static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index, > uint16_t mask, source_id; > uint8_t bus, bus_max, bus_min; > > + if (index >= iommu->intr_size) { > + error_report_once("%s: index too large: ind=0x%x", > + __func__, index); > + return -VTD_FR_IR_INDEX_OVER; > + } > + > addr = iommu->intr_root + index * sizeof(*entry); > if (dma_memory_read(&address_space_memory, addr, entry, > sizeof(*entry))) { > Queued, thanks. Paolo
On Tue, Mar 10, 2020 at 06:42:11PM +0100, Jan Kiszka wrote: > From: Jan Kiszka <jan.kiszka@siemens.com> > > vtd_irte_get failed to check the index against the configured table > size, causing an out-of-bounds access on guest memory and potentially > misinterpreting the result. > > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Reviewed-by: Peter Xu <peterx@redhat.com> > --- > > BTW, we still miss error reporting emulation, right? Therefore, I added > that simple error_report_once thing, like the other paths do. Yes... Thanks,
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 204b6841ec..df7ad254ac 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3094,6 +3094,12 @@ static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index, uint16_t mask, source_id; uint8_t bus, bus_max, bus_min; + if (index >= iommu->intr_size) { + error_report_once("%s: index too large: ind=0x%x", + __func__, index); + return -VTD_FR_IR_INDEX_OVER; + } + addr = iommu->intr_root + index * sizeof(*entry); if (dma_memory_read(&address_space_memory, addr, entry, sizeof(*entry))) {