From 936335aa5e880892560dbe04ba59cc9e3188f18e Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 14 Sep 2021 14:21:46 +0800 Subject: [PATCH] vfio/common: Add address alignment check in vfio_listener_region_del Both vfio_listener_region_add and vfio_listener_region_del have reference counting operations on ram section->mr. If the 'iova' and 'llend' of the ram section do not pass the alignment check, the ram section should not be mapped or unmapped. It means that the reference counting should not be changed. However, the address alignment check is missing in vfio_listener_region_del. This makes memory_region_unref will be unconditional called and causes unintended problems in some scenarios. Signed-off-by: Kunkun Jiang Signed-off-by: imxcc (cherry picked from commit c4568a05c1d9f9017c89abc9df4270ce128a9cc3) --- ...address-alignment-check-in-vfio_list.patch | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 vfio-common-Add-address-alignment-check-in-vfio_list.patch diff --git a/vfio-common-Add-address-alignment-check-in-vfio_list.patch b/vfio-common-Add-address-alignment-check-in-vfio_list.patch new file mode 100644 index 0000000..288f284 --- /dev/null +++ b/vfio-common-Add-address-alignment-check-in-vfio_list.patch @@ -0,0 +1,53 @@ +From 00c553f53657bf4bc165d859187215dba7110246 Mon Sep 17 00:00:00 2001 +From: Kunkun Jiang +Date: Tue, 14 Sep 2021 14:21:46 +0800 +Subject: [PATCH] vfio/common: Add address alignment check in + vfio_listener_region_del + +Both vfio_listener_region_add and vfio_listener_region_del have +reference counting operations on ram section->mr. If the 'iova' +and 'llend' of the ram section do not pass the alignment +check, the ram section should not be mapped or unmapped. It means +that the reference counting should not be changed. + +However, the address alignment check is missing in +vfio_listener_region_del. This makes memory_region_unref will +be unconditional called and causes unintended problems in some +scenarios. + +Signed-off-by: Kunkun Jiang +--- + hw/vfio/common.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/hw/vfio/common.c b/hw/vfio/common.c +index 89c49f5508..4d45c2b625 100644 +--- a/hw/vfio/common.c ++++ b/hw/vfio/common.c +@@ -1411,6 +1411,8 @@ static void vfio_listener_region_del(MemoryListener *listener, + MemoryRegionSection *section) + { + VFIOContainer *container = container_of(listener, VFIOContainer, listener); ++ hwaddr iova; ++ Int128 llend; + + if (vfio_listener_skipped_section(section)) { + trace_vfio_listener_region_del_skip( +@@ -1460,6 +1462,14 @@ static void vfio_listener_region_del(MemoryListener *listener, + */ + } + ++ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); ++ llend = int128_make64(section->offset_within_address_space); ++ llend = int128_add(llend, section->size); ++ llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); ++ if (int128_ge(int128_make64(iova), llend)) { ++ return; ++ } ++ + vfio_dma_unmap_ram_section(container, section); + + memory_region_unref(section->mr); +-- +2.27.0 +