diff options
author | Daniel Henrique Barboza <danielhb413@gmail.com> | 2022-04-09 17:08:56 -0300 |
---|---|---|
committer | Daniel Henrique Barboza <danielhb413@gmail.com> | 2022-07-28 10:31:54 -0300 |
commit | edccf661e6205d5ffff73860ab22eaf08a611ad9 (patch) | |
tree | aa4480e68612129eb0e2ad12cf02e3ba24aa5af6 /hw/ppc/spapr_nvdimm.c | |
parent | 3e4abe2c92964aadd35344a635b0f32cb487fd5c (diff) | |
download | qemu-edccf661e6205d5ffff73860ab22eaf08a611ad9.zip qemu-edccf661e6205d5ffff73860ab22eaf08a611ad9.tar.gz qemu-edccf661e6205d5ffff73860ab22eaf08a611ad9.tar.bz2 |
hw/ppc: check if spapr_drc_index() returns NULL in spapr_nvdimm.c
spapr_nvdimm_flush_completion_cb() and flush_worker_cb() are using the
DRC object returned by spapr_drc_index() without checking it for NULL.
In this case we would be dereferencing a NULL pointer when doing
SPAPR_NVDIMM(drc->dev) and PC_DIMM(drc->dev).
This can happen if, during a scm_flush(), the DRC object is wrongly
freed/released (e.g. a bug in another part of the code).
spapr_drc_index() would then return NULL in the callbacks.
Fixes: Coverity CID 1487108, 1487178
Reviewed-by: Greg Kurz <groug@kaod.org>
Message-Id: <20220409200856.283076-2-danielhb413@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'hw/ppc/spapr_nvdimm.c')
-rw-r--r-- | hw/ppc/spapr_nvdimm.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index c4c97da..04a64ca 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -447,9 +447,15 @@ static int flush_worker_cb(void *opaque) { SpaprNVDIMMDeviceFlushState *state = opaque; SpaprDrc *drc = spapr_drc_by_index(state->drcidx); - PCDIMMDevice *dimm = PC_DIMM(drc->dev); - HostMemoryBackend *backend = MEMORY_BACKEND(dimm->hostmem); - int backend_fd = memory_region_get_fd(&backend->mr); + PCDIMMDevice *dimm; + HostMemoryBackend *backend; + int backend_fd; + + g_assert(drc != NULL); + + dimm = PC_DIMM(drc->dev); + backend = MEMORY_BACKEND(dimm->hostmem); + backend_fd = memory_region_get_fd(&backend->mr); if (object_property_get_bool(OBJECT(backend), "pmem", NULL)) { MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem); @@ -475,7 +481,11 @@ static void spapr_nvdimm_flush_completion_cb(void *opaque, int hcall_ret) { SpaprNVDIMMDeviceFlushState *state = opaque; SpaprDrc *drc = spapr_drc_by_index(state->drcidx); - SpaprNVDIMMDevice *s_nvdimm = SPAPR_NVDIMM(drc->dev); + SpaprNVDIMMDevice *s_nvdimm; + + g_assert(drc != NULL); + + s_nvdimm = SPAPR_NVDIMM(drc->dev); state->hcall_ret = hcall_ret; QLIST_REMOVE(state, node); |