aboutsummaryrefslogtreecommitdiff
path: root/lib/dma.c
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-11-24 23:59:24 +0000
committerGitHub <noreply@github.com>2021-11-24 23:59:24 +0000
commit02174878b1f7a70d3ac09c50c12799df0a1f9406 (patch)
tree62cdd8b99de889d310a65ddbdf2ad5b5257f403d /lib/dma.c
parentd8a08f1a18370bcad4fa99a16bdbfc63dbbd35ad (diff)
downloadlibvfio-user-02174878b1f7a70d3ac09c50c12799df0a1f9406.zip
libvfio-user-02174878b1f7a70d3ac09c50c12799df0a1f9406.tar.gz
libvfio-user-02174878b1f7a70d3ac09c50c12799df0a1f9406.tar.bz2
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 <john.levon@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/dma.c')
-rw-r--r--lib/dma.c12
1 files changed, 12 insertions, 0 deletions
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().