All of lore.kernel.org
 help / color / mirror / Atom feed
* [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read
@ 2023-03-25 14:42 kai.kang
  2023-03-25 14:42 ` [dunfell][PATCH v2 2/2] qemu: fix compile error kai.kang
  2023-03-27 14:11 ` [OE-core] [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read Steve Sakoman
  0 siblings, 2 replies; 3+ messages in thread
From: kai.kang @ 2023-03-25 14:42 UTC (permalink / raw)
  To: openembedded-core

From: Hitendra Prajapati <hprajapati@mvista.com>

Upstream-Status: Backport from https://gitlab.com/qemu-project/qemu/-/commit/6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622

Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>

Replace the tabs with spaces to correct the indent.

Signed-off-by: Kai Kang <kai.kang@windriver.com>
---
 meta/recipes-devtools/qemu/qemu.inc           |   9 +-
 .../qemu/qemu/CVE-2022-4144.patch             | 103 ++++++++++++++++++
 2 files changed, 108 insertions(+), 4 deletions(-)
 create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch

diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index 36d0b9320f..0649727338 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -112,10 +112,11 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
            file://CVE-2022-0216-1.patch \
            file://CVE-2022-0216-2.patch \
            file://CVE-2021-3750.patch \
-	   file://CVE-2021-3638.patch \
-	   file://CVE-2021-20196.patch \
-	   file://CVE-2021-3507.patch \
-	   file://CVE-2021-3929.patch \
+           file://CVE-2021-3638.patch \
+           file://CVE-2021-20196.patch \
+           file://CVE-2021-3507.patch \
+           file://CVE-2021-3929.patch \
+           file://CVE-2022-4144.patch \
            "
 UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
 
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch b/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch
new file mode 100644
index 0000000000..3f0d5fbd5c
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch
@@ -0,0 +1,103 @@
+From 6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 28 Nov 2022 21:27:40 +0100
+Subject: [PATCH] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt
+ (CVE-2022-4144)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Have qxl_get_check_slot_offset() return false if the requested
+buffer size does not fit within the slot memory region.
+
+Similarly qxl_phys2virt() now returns NULL in such case, and
+qxl_dirty_one_surface() aborts.
+
+This avoids buffer overrun in the host pointer returned by
+memory_region_get_ram_ptr().
+
+Fixes: CVE-2022-4144 (out-of-bounds read)
+Reported-by: Wenxu Yin (@awxylitol)
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1336
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20221128202741.4945-5-philmd@linaro.org>
+
+Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622]
+CVE: CVE-2022-4144
+Comments: Deleted patch hunk in qxl.h,as it contains change
+in comments which is not present in current version of qemu.
+
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ hw/display/qxl.c | 27 +++++++++++++++++++++++----
+ 1 file changed, 23 insertions(+), 4 deletions(-)
+
+diff --git a/hw/display/qxl.c b/hw/display/qxl.c
+index cd7eb39d..6bc8385b 100644
+--- a/hw/display/qxl.c
++++ b/hw/display/qxl.c
+@@ -1440,11 +1440,13 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
+ 
+ /* can be also called from spice server thread context */
+ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+-                                      uint32_t *s, uint64_t *o)
++                                      uint32_t *s, uint64_t *o,
++                                      size_t size_requested)
+ {
+     uint64_t phys   = le64_to_cpu(pqxl);
+     uint32_t slot   = (phys >> (64 -  8)) & 0xff;
+     uint64_t offset = phys & 0xffffffffffff;
++    uint64_t size_available;
+ 
+     if (slot >= NUM_MEMSLOTS) {
+         qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
+@@ -1468,6 +1470,23 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+                           slot, offset, qxl->guest_slots[slot].size);
+         return false;
+     }
++    size_available = memory_region_size(qxl->guest_slots[slot].mr);
++    if (qxl->guest_slots[slot].offset + offset >= size_available) {
++        qxl_set_guest_bug(qxl,
++                          "slot %d offset %"PRIu64" > region size %"PRIu64"\n",
++                          slot, qxl->guest_slots[slot].offset + offset,
++                          size_available);
++        return false;
++    }
++    size_available -= qxl->guest_slots[slot].offset + offset;
++    if (size_requested > size_available) {
++        qxl_set_guest_bug(qxl,
++                          "slot %d offset %"PRIu64" size %zu: "
++                          "overrun by %"PRIu64" bytes\n",
++                          slot, offset, size_requested,
++                          size_requested - size_available);
++        return false;
++    }
+ 
+     *s = slot;
+     *o = offset;
+@@ -1486,7 +1505,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
+         offset = le64_to_cpu(pqxl) & 0xffffffffffff;
+         return (void *)(intptr_t)offset;
+     case MEMSLOT_GROUP_GUEST:
+-        if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
++        if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
+             return NULL;
+         }
+         ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
+@@ -1944,9 +1963,9 @@ static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+     uint32_t slot;
+     bool rc;
+ 
+-    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
+-    assert(rc == true);
+     size = (uint64_t)height * abs(stride);
++    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size);
++    assert(rc == true);
+     trace_qxl_surfaces_dirty(qxl->id, offset, size);
+     qxl_set_dirty(qxl->guest_slots[slot].mr,
+                   qxl->guest_slots[slot].offset + offset,
+-- 
+2.25.1
+
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [dunfell][PATCH v2 2/2] qemu: fix compile error
  2023-03-25 14:42 [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read kai.kang
@ 2023-03-25 14:42 ` kai.kang
  2023-03-27 14:11 ` [OE-core] [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read Steve Sakoman
  1 sibling, 0 replies; 3+ messages in thread
From: kai.kang @ 2023-03-25 14:42 UTC (permalink / raw)
  To: openembedded-core

From: Kai Kang <kai.kang@windriver.com>

Backport 2 patches and rebase
0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch to fix
compile error:

../qemu-6.2.0/hw/display/qxl.c: In function 'qxl_phys2virt':
../qemu-6.2.0/hw/display/qxl.c:1477:67: error: 'size' undeclared (first use in this function); did you mean 'gsize'?
 1477 |         if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
      |                                                                   ^~~~
      |                                                                   gsize
../qemu-6.2.0/hw/display/qxl.c:1477:67: note: each undeclared identifier is reported only once for each function it appears in

(From OE-Core rev: b3f42317c1932253e7e6b2fd7a263bdbd6c2f69a)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
v2: update context of 0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch

 meta/recipes-devtools/qemu/qemu.inc           |   2 +
 ...ave-qxl_log_command-Return-early-if-.patch |  57 +++++
 ...ass-requested-buffer-size-to-qxl_phy.patch | 217 ++++++++++++++++++
 3 files changed, 276 insertions(+)
 create mode 100644 meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch
 create mode 100644 meta/recipes-devtools/qemu/qemu/0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch

diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index 0649727338..db3b91fb4c 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -117,6 +117,8 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
            file://CVE-2021-3507.patch \
            file://CVE-2021-3929.patch \
            file://CVE-2022-4144.patch \
+           file://0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch \
+           file://0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch \
            "
 UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
 
diff --git a/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch b/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch
new file mode 100644
index 0000000000..cd846222c9
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch
@@ -0,0 +1,57 @@
+Upstream-Status: Backport [https://github.com/qemu/qemu/commit/61c34fc]
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+
+From 61c34fc194b776ecadc39fb26b061331107e5599 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 28 Nov 2022 21:27:37 +0100
+Subject: [PATCH] hw/display/qxl: Have qxl_log_command Return early if no
+ log_cmd handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only 3 command types are logged: no need to call qxl_phys2virt()
+for the other types. Using different cases will help to pass
+different structure sizes to qxl_phys2virt() in a pair of commits.
+
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20221128202741.4945-2-philmd@linaro.org>
+---
+ hw/display/qxl-logger.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c
+index 68bfa47568..1bcf803db6 100644
+--- a/hw/display/qxl-logger.c
++++ b/hw/display/qxl-logger.c
+@@ -247,6 +247,16 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
+             qxl_name(qxl_type, ext->cmd.type),
+             compat ? "(compat)" : "");
+ 
++    switch (ext->cmd.type) {
++    case QXL_CMD_DRAW:
++        break;
++    case QXL_CMD_SURFACE:
++        break;
++    case QXL_CMD_CURSOR:
++        break;
++    default:
++        goto out;
++    }
+     data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+     if (!data) {
+         return 1;
+@@ -269,6 +279,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
+         qxl_log_cmd_cursor(qxl, data, ext->group_id);
+         break;
+     }
++out:
+     fprintf(stderr, "\n");
+     return 0;
+ }
+-- 
+2.34.1
+
diff --git a/meta/recipes-devtools/qemu/qemu/0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch b/meta/recipes-devtools/qemu/qemu/0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch
new file mode 100644
index 0000000000..5a9d7f4b5e
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/0002-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch
@@ -0,0 +1,217 @@
+Upstream-Status: Backport [https://github.com/qemu/qemu/commit/8efec0e]
+
+Backport and rebase patch to fix compile error which imported by CVE-2022-4144.patch:
+
+../qemu-6.2.0/hw/display/qxl.c: In function 'qxl_phys2virt':
+../qemu-6.2.0/hw/display/qxl.c:1477:67: error: 'size' undeclared (first use in this function); did you mean 'gsize'?
+	1477 |         if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
+		|                                                                   ^~~~
+		|                                                                   gsize
+../qemu-6.2.0/hw/display/qxl.c:1477:67: note: each undeclared identifier is reported only once for each function it appears in
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+
+From 8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 28 Nov 2022 21:27:39 +0100
+Subject: [PATCH] hw/display/qxl: Pass requested buffer size to qxl_phys2virt()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently qxl_phys2virt() doesn't check for buffer overrun.
+In order to do so in the next commit, pass the buffer size
+as argument.
+
+For QXLCursor in qxl_render_cursor() -> qxl_cursor() we
+verify the size of the chunked data ahead, checking we can
+access 'sizeof(QXLCursor) + chunk->data_size' bytes.
+Since in the SPICE_CURSOR_TYPE_MONO case the cursor is
+assumed to fit in one chunk, no change are required.
+In SPICE_CURSOR_TYPE_ALPHA the ahead read is handled in
+qxl_unpack_chunks().
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20221128202741.4945-4-philmd@linaro.org>
+---
+ hw/display/qxl-logger.c | 11 ++++++++---
+ hw/display/qxl-render.c | 20 ++++++++++++++++----
+ hw/display/qxl.c        | 14 +++++++++-----
+ hw/display/qxl.h        |  3 ++-
+ 4 files changed, 35 insertions(+), 13 deletions(-)
+
+diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c
+index 551c274..031ddfe 100644
+--- a/hw/display/qxl-logger.c
++++ b/hw/display/qxl-logger.c
+@@ -106,7 +106,7 @@ static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
+     QXLImage *image;
+     QXLImageDescriptor *desc;
+ 
+-    image = qxl_phys2virt(qxl, addr, group_id);
++    image = qxl_phys2virt(qxl, addr, group_id, sizeof(QXLImage));
+     if (!image) {
+         return 1;
+     }
+@@ -216,7 +216,8 @@ int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
+                 cmd->u.set.position.y,
+                 cmd->u.set.visible ? "yes" : "no",
+                 cmd->u.set.shape);
+-        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id);
++        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id,
++                               sizeof(QXLCursor));
+         if (!cursor) {
+             return 1;
+         }
+@@ -238,6 +239,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
+ {
+     bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT;
+     void *data;
++    size_t datasz;
+     int ret;
+ 
+     if (!qxl->cmdlog) {
+@@ -251,15 +253,18 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
+ 
+     switch (ext->cmd.type) {
+     case QXL_CMD_DRAW:
++        datasz = compat ? sizeof(QXLCompatDrawable) : sizeof(QXLDrawable);
+         break;
+     case QXL_CMD_SURFACE:
++        datasz = sizeof(QXLSurfaceCmd);
+         break;
+     case QXL_CMD_CURSOR:
++        datasz = sizeof(QXLCursorCmd);
+         break;
+     default:
+         goto out;
+     }
+-    data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
++    data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, datasz);
+     if (!data) {
+         return 1;
+     }
+diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
+index d532e15..a65a6d6 100644
+--- a/hw/display/qxl-render.c
++++ b/hw/display/qxl-render.c
+@@ -107,7 +107,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
+         qxl->guest_primary.resized = 0;
+         qxl->guest_primary.data = qxl_phys2virt(qxl,
+                                                 qxl->guest_primary.surface.mem,
+-                                                MEMSLOT_GROUP_GUEST);
++                                                MEMSLOT_GROUP_GUEST,
++                                                qxl->guest_primary.abs_stride
++                                                * height);
+         if (!qxl->guest_primary.data) {
+             return;
+         }
+@@ -222,7 +224,8 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
+         if (offset == size) {
+             return;
+         }
+-        chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id);
++        chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id,
++                              sizeof(QXLDataChunk) + chunk->data_size);
+         if (!chunk) {
+             return;
+         }
+@@ -289,7 +292,8 @@ fail:
+ /* called from spice server thread context only */
+ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
+ {
+-    QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
++    QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
++                                      sizeof(QXLCursorCmd));
+     QXLCursor *cursor;
+     QEMUCursor *c;
+ 
+@@ -308,7 +312,15 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
+     }
+     switch (cmd->type) {
+     case QXL_CURSOR_SET:
+-        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id);
++        /* First read the QXLCursor to get QXLDataChunk::data_size ... */
++        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id,
++                               sizeof(QXLCursor));
++        if (!cursor) {
++            return 1;
++        }
++        /* Then read including the chunked data following QXLCursor. */
++        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id,
++                               sizeof(QXLCursor) + cursor->chunk.data_size);
+         if (!cursor) {
+             return 1;
+         }
+diff --git a/hw/display/qxl.c b/hw/display/qxl.c
+index 6bc8385..8792b58 100644
+--- a/hw/display/qxl.c
++++ b/hw/display/qxl.c
+@@ -275,7 +275,8 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
+                                           QXL_IO_MONITORS_CONFIG_ASYNC));
+     }
+ 
+-    cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST);
++    cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST,
++                        sizeof(QXLMonitorsConfig));
+     if (cfg != NULL && cfg->count == 1) {
+         qxl->guest_primary.resized = 1;
+         qxl->guest_head0_width  = cfg->heads[0].width;
+@@ -460,7 +461,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
+     switch (le32_to_cpu(ext->cmd.type)) {
+     case QXL_CMD_SURFACE:
+     {
+-        QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
++        QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
++                                           sizeof(QXLSurfaceCmd));
+ 
+         if (!cmd) {
+             return 1;
+@@ -494,7 +496,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
+     }
+     case QXL_CMD_CURSOR:
+     {
+-        QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
++        QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
++                                          sizeof(QXLCursorCmd));
+ 
+         if (!cmd) {
+             return 1;
+@@ -1494,7 +1497,8 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
+ }
+ 
+ /* can be also called from spice server thread context */
+-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
++void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
++                    size_t size)
+ {
+     uint64_t offset;
+     uint32_t slot;
+@@ -1994,7 +1998,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
+         }
+ 
+         cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
+-                            MEMSLOT_GROUP_GUEST);
++                            MEMSLOT_GROUP_GUEST, sizeof(QXLSurfaceCmd));
+         assert(cmd);
+         assert(cmd->type == QXL_SURFACE_CMD_CREATE);
+         qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
+diff --git a/hw/display/qxl.h b/hw/display/qxl.h
+index 80eb0d2..fcfd133 100644
+--- a/hw/display/qxl.h
++++ b/hw/display/qxl.h
+@@ -147,7 +147,8 @@ typedef struct PCIQXLDevice {
+ #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
+ 
+ /* qxl.c */
+-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
++void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id,
++                    size_t size);
+ void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
+     GCC_FMT_ATTR(2, 3);
+ 
+-- 
+2.34.1
+
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [OE-core] [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read
  2023-03-25 14:42 [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read kai.kang
  2023-03-25 14:42 ` [dunfell][PATCH v2 2/2] qemu: fix compile error kai.kang
@ 2023-03-27 14:11 ` Steve Sakoman
  1 sibling, 0 replies; 3+ messages in thread
From: Steve Sakoman @ 2023-03-27 14:11 UTC (permalink / raw)
  To: Kai Kang; +Cc: openembedded-core

We already seem to have a version of this patch in dunfell:

https://git.openembedded.org/openembedded-core/commit/?h=dunfell&id=754cce68614c7985d5848134635a6b318f4505ab

If you have corrections to the above patch, please submit a patch with
those corrections.

Thanks!

Steve


On Sat, Mar 25, 2023 at 4:42 AM Kai Kang <kai.kang@eng.windriver.com> wrote:
>
> From: Hitendra Prajapati <hprajapati@mvista.com>
>
> Upstream-Status: Backport from https://gitlab.com/qemu-project/qemu/-/commit/6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622
>
> Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
> Signed-off-by: Steve Sakoman <steve@sakoman.com>
>
> Replace the tabs with spaces to correct the indent.
>
> Signed-off-by: Kai Kang <kai.kang@windriver.com>
> ---
>  meta/recipes-devtools/qemu/qemu.inc           |   9 +-
>  .../qemu/qemu/CVE-2022-4144.patch             | 103 ++++++++++++++++++
>  2 files changed, 108 insertions(+), 4 deletions(-)
>  create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch
>
> diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
> index 36d0b9320f..0649727338 100644
> --- a/meta/recipes-devtools/qemu/qemu.inc
> +++ b/meta/recipes-devtools/qemu/qemu.inc
> @@ -112,10 +112,11 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
>             file://CVE-2022-0216-1.patch \
>             file://CVE-2022-0216-2.patch \
>             file://CVE-2021-3750.patch \
> -          file://CVE-2021-3638.patch \
> -          file://CVE-2021-20196.patch \
> -          file://CVE-2021-3507.patch \
> -          file://CVE-2021-3929.patch \
> +           file://CVE-2021-3638.patch \
> +           file://CVE-2021-20196.patch \
> +           file://CVE-2021-3507.patch \
> +           file://CVE-2021-3929.patch \
> +           file://CVE-2022-4144.patch \
>             "
>  UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
>
> diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch b/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch
> new file mode 100644
> index 0000000000..3f0d5fbd5c
> --- /dev/null
> +++ b/meta/recipes-devtools/qemu/qemu/CVE-2022-4144.patch
> @@ -0,0 +1,103 @@
> +From 6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622 Mon Sep 17 00:00:00 2001
> +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
> +Date: Mon, 28 Nov 2022 21:27:40 +0100
> +Subject: [PATCH] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt
> + (CVE-2022-4144)
> +MIME-Version: 1.0
> +Content-Type: text/plain; charset=UTF-8
> +Content-Transfer-Encoding: 8bit
> +
> +Have qxl_get_check_slot_offset() return false if the requested
> +buffer size does not fit within the slot memory region.
> +
> +Similarly qxl_phys2virt() now returns NULL in such case, and
> +qxl_dirty_one_surface() aborts.
> +
> +This avoids buffer overrun in the host pointer returned by
> +memory_region_get_ram_ptr().
> +
> +Fixes: CVE-2022-4144 (out-of-bounds read)
> +Reported-by: Wenxu Yin (@awxylitol)
> +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1336
> +
> +Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> +Message-Id: <20221128202741.4945-5-philmd@linaro.org>
> +
> +Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/6dbbf055148c6f1b7d8a3251a65bd6f3d1e1f622]
> +CVE: CVE-2022-4144
> +Comments: Deleted patch hunk in qxl.h,as it contains change
> +in comments which is not present in current version of qemu.
> +
> +Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
> +---
> + hw/display/qxl.c | 27 +++++++++++++++++++++++----
> + 1 file changed, 23 insertions(+), 4 deletions(-)
> +
> +diff --git a/hw/display/qxl.c b/hw/display/qxl.c
> +index cd7eb39d..6bc8385b 100644
> +--- a/hw/display/qxl.c
> ++++ b/hw/display/qxl.c
> +@@ -1440,11 +1440,13 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
> +
> + /* can be also called from spice server thread context */
> + static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
> +-                                      uint32_t *s, uint64_t *o)
> ++                                      uint32_t *s, uint64_t *o,
> ++                                      size_t size_requested)
> + {
> +     uint64_t phys   = le64_to_cpu(pqxl);
> +     uint32_t slot   = (phys >> (64 -  8)) & 0xff;
> +     uint64_t offset = phys & 0xffffffffffff;
> ++    uint64_t size_available;
> +
> +     if (slot >= NUM_MEMSLOTS) {
> +         qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
> +@@ -1468,6 +1470,23 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
> +                           slot, offset, qxl->guest_slots[slot].size);
> +         return false;
> +     }
> ++    size_available = memory_region_size(qxl->guest_slots[slot].mr);
> ++    if (qxl->guest_slots[slot].offset + offset >= size_available) {
> ++        qxl_set_guest_bug(qxl,
> ++                          "slot %d offset %"PRIu64" > region size %"PRIu64"\n",
> ++                          slot, qxl->guest_slots[slot].offset + offset,
> ++                          size_available);
> ++        return false;
> ++    }
> ++    size_available -= qxl->guest_slots[slot].offset + offset;
> ++    if (size_requested > size_available) {
> ++        qxl_set_guest_bug(qxl,
> ++                          "slot %d offset %"PRIu64" size %zu: "
> ++                          "overrun by %"PRIu64" bytes\n",
> ++                          slot, offset, size_requested,
> ++                          size_requested - size_available);
> ++        return false;
> ++    }
> +
> +     *s = slot;
> +     *o = offset;
> +@@ -1486,7 +1505,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
> +         offset = le64_to_cpu(pqxl) & 0xffffffffffff;
> +         return (void *)(intptr_t)offset;
> +     case MEMSLOT_GROUP_GUEST:
> +-        if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
> ++        if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
> +             return NULL;
> +         }
> +         ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
> +@@ -1944,9 +1963,9 @@ static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
> +     uint32_t slot;
> +     bool rc;
> +
> +-    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
> +-    assert(rc == true);
> +     size = (uint64_t)height * abs(stride);
> ++    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size);
> ++    assert(rc == true);
> +     trace_qxl_surfaces_dirty(qxl->id, offset, size);
> +     qxl_set_dirty(qxl->guest_slots[slot].mr,
> +                   qxl->guest_slots[slot].offset + offset,
> +--
> +2.25.1
> +
> --
> 2.17.1
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#179097): https://lists.openembedded.org/g/openembedded-core/message/179097
> Mute This Topic: https://lists.openembedded.org/mt/97844421/3620601
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-03-27 14:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-25 14:42 [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read kai.kang
2023-03-25 14:42 ` [dunfell][PATCH v2 2/2] qemu: fix compile error kai.kang
2023-03-27 14:11 ` [OE-core] [dunfell][PATCH v2 1/2] QEMU: CVE-2022-4144 QXL: qxl_phys2virt unsafe address translation can lead to out-of-bounds read Steve Sakoman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.