Message ID | 20210714060125.994882-4-its@irrelevant.dk |
---|---|
State | New |
Headers | show |
Series | hw/nvme: fix mmio read | expand |
On Wed, Jul 14, 2021 at 08:01:23AM +0200, Klaus Jensen wrote: > From: Klaus Jensen <k.jensen@samsung.com> > > Peter noticed that mmio access may read into the NvmeParams member in > the NvmeCtrl struct. > > Fix the bounds check. > > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Klaus Jensen <k.jensen@samsung.com> > --- > hw/nvme/ctrl.c | 27 +++++++++++++++------------ > 1 file changed, 15 insertions(+), 12 deletions(-) Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
On Wed, 14 Jul 2021 at 07:01, Klaus Jensen <its@irrelevant.dk> wrote: > > From: Klaus Jensen <k.jensen@samsung.com> > > Peter noticed that mmio access may read into the NvmeParams member in > the NvmeCtrl struct. > > Fix the bounds check. > > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Klaus Jensen <k.jensen@samsung.com> > --- > hw/nvme/ctrl.c | 27 +++++++++++++++------------ > 1 file changed, 15 insertions(+), 12 deletions(-) Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 8c305315f41c..0449cc4dee9b 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -5968,23 +5968,26 @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size) /* should RAZ, fall through for now */ } - if (addr < sizeof(n->bar)) { - /* - * When PMRWBM bit 1 is set then read from - * from PMRSTS should ensure prior writes - * made it to persistent media - */ - if (addr == NVME_REG_PMRSTS && - (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) { - memory_region_msync(&n->pmr.dev->mr, 0, n->pmr.dev->size); - } - memcpy(&val, ptr + addr, size); - } else { + if (addr > sizeof(n->bar) - size) { NVME_GUEST_ERR(pci_nvme_ub_mmiord_invalid_ofs, "MMIO read beyond last register," " offset=0x%"PRIx64", returning 0", addr); + + return 0; } + /* + * When PMRWBM bit 1 is set then read from + * from PMRSTS should ensure prior writes + * made it to persistent media + */ + if (addr == NVME_REG_PMRSTS && + (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) { + memory_region_msync(&n->pmr.dev->mr, 0, n->pmr.dev->size); + } + + memcpy(&val, ptr + addr, size); + return val; }