[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH-for-7.2 4/4] hw/display/qxl: Avoid buffer overrun in qxl_phys
From: |
Philippe Mathieu-Daudé |
Subject: |
[RFC PATCH-for-7.2 4/4] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt (CVE-2022-4144) |
Date: |
Fri, 25 Nov 2022 18:31:19 +0100 |
Return NULL if the requested buffer size does not fit
within the slot memory region.
Reported-by: Wenxu Yin (@awxylitol)
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1336
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/display/qxl.c | 11 ++++++++++-
hw/display/qxl.h | 2 +-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 231d733250..e5e162f82d 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1462,7 +1462,7 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl,
QXLPHYSICAL pqxl,
void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
size_t size)
{
- uint64_t offset;
+ uint64_t offset, ptr_end_offset;
uint32_t slot;
void *ptr;
@@ -1474,6 +1474,15 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
int group_id,
if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
return NULL;
}
+
+ ptr_end_offset = qxl->guest_slots[slot].offset + offset + size;
+ if (ptr_end_offset > memory_region_size(qxl->guest_slots[slot].mr)) {
+ qxl_set_guest_bug(qxl,
+ "slot %d offset %"PRIu64" size %zu: "
+ "overrun by %"PRIu64" bytes\n",
+ slot, offset, size, ptr_end_offset - offset);
+ return NULL;
+ }
ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
ptr += qxl->guest_slots[slot].offset;
ptr += offset;
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index bf03138ab4..7894bd5134 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -157,7 +157,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL)
*
* Returns a host pointer to a buffer placed at offset @phys within the
* active slot @group_id of the PCI VGA RAM memory region associated with
- * the @qxl device. If the slot is inactive, or the offset is out
+ * the @qxl device. If the slot is inactive, or the offset + size are out
* of the memory region, returns NULL.
*
* Use with care; by the time this function returns, the returned pointer is
--
2.38.1
- [RFC PATCH-for-7.2 0/4] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt(), Philippe Mathieu-Daudé, 2022/11/25
- [RFC PATCH-for-7.2 1/4] hw/display/qxl: Have qxl_log_command Return early if no log_cmd handler, Philippe Mathieu-Daudé, 2022/11/25
- [RFC PATCH-for-7.2 2/4] hw/display/qxl: Document qxl_phys2virt(), Philippe Mathieu-Daudé, 2022/11/25
- Re: [RFC PATCH-for-7.2 0/4] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt(), Mauro Matteo Cascella, 2022/11/25
- [RFC PATCH-for-7.2 3/4] hw/display/qxl: Pass requested buffer size to qxl_phys2virt(), Philippe Mathieu-Daudé, 2022/11/25
- [RFC PATCH-for-7.2 4/4] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt (CVE-2022-4144),
Philippe Mathieu-Daudé <=
- Re: [RFC PATCH-for-7.2 3/4] hw/display/qxl: Pass requested buffer size to qxl_phys2virt(), Marc-André Lureau, 2022/11/28
- Re: [RFC PATCH-for-7.2 0/4] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt(), Philippe Mathieu-Daudé, 2022/11/25