From 02174878b1f7a70d3ac09c50c12799df0a1f9406 Mon Sep 17 00:00:00 2001 From: John Levon Date: Wed, 24 Nov 2021 23:59:24 +0000 Subject: verify region is mapped before acquiring dirty bitmap (#627) DMA regions not mapped by the server are not dirty tracked (the client must track changes via handling VFIO_USER_DMA_WRITE), but we weren't correctly enforcing this, which could segfault when ->dirty_bitmap was NULL. Found via AFL++. Signed-off-by: John Levon Reviewed-by: Thanos Makatos --- lib/dma.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib') diff --git a/lib/dma.c b/lib/dma.c index ffc0b6b..eed4370 100644 --- a/lib/dma.c +++ b/lib/dma.c @@ -285,6 +285,8 @@ get_bitmap_size(size_t region_size, size_t pgsize) static int dirty_page_logging_start_on_region(dma_memory_region_t *region, size_t pgsize) { + assert(region->fd != -1); + ssize_t size = get_bitmap_size(region->info.iova.iov_len, pgsize); if (size < 0) { return size; @@ -511,6 +513,11 @@ dma_controller_dirty_page_logging_start(dma_controller_t *dma, size_t pgsize) for (i = 0; i < (size_t)dma->nregions; i++) { dma_memory_region_t *region = &dma->regions[i]; + + if (region->fd == -1) { + continue; + } + if (dirty_page_logging_start_on_region(region, pgsize) < 0) { int _errno = errno; size_t j; @@ -594,6 +601,11 @@ dma_controller_dirty_page_get(dma_controller_t *dma, vfu_dma_addr_t addr, region = &dma->regions[sg.region]; + if (region->fd == -1) { + vfu_log(dma->vfu_ctx, LOG_ERR, "region %d is not mapped", sg.region); + return ERROR_INT(EINVAL); + } + /* * TODO race condition between resetting bitmap and user calling * vfu_map_sg/vfu_unmap_sg(). -- cgit v1.1