diff options
3 files changed, 276 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index b68be447f1..5430718f75 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
| @@ -93,6 +93,8 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
| 93 | file://0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch \ | 93 | file://0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch \ |
| 94 | file://CVE-2022-3165.patch \ | 94 | file://CVE-2022-3165.patch \ |
| 95 | file://CVE-2022-4144.patch \ | 95 | file://CVE-2022-4144.patch \ |
| 96 | file://0001-hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch \ | ||
| 97 | file://0001-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch \ | ||
| 96 | " | 98 | " |
| 97 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 99 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
| 98 | 100 | ||
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 @@ | |||
| 1 | Upstream-Status: Backport [https://github.com/qemu/qemu/commit/61c34fc] | ||
| 2 | |||
| 3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
| 4 | |||
| 5 | From 61c34fc194b776ecadc39fb26b061331107e5599 Mon Sep 17 00:00:00 2001 | ||
| 6 | From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org> | ||
| 7 | Date: Mon, 28 Nov 2022 21:27:37 +0100 | ||
| 8 | Subject: [PATCH] hw/display/qxl: Have qxl_log_command Return early if no | ||
| 9 | log_cmd handler | ||
| 10 | MIME-Version: 1.0 | ||
| 11 | Content-Type: text/plain; charset=UTF-8 | ||
| 12 | Content-Transfer-Encoding: 8bit | ||
| 13 | |||
| 14 | Only 3 command types are logged: no need to call qxl_phys2virt() | ||
| 15 | for the other types. Using different cases will help to pass | ||
| 16 | different structure sizes to qxl_phys2virt() in a pair of commits. | ||
| 17 | |||
| 18 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | ||
| 19 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 20 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
| 21 | Message-Id: <20221128202741.4945-2-philmd@linaro.org> | ||
| 22 | --- | ||
| 23 | hw/display/qxl-logger.c | 11 +++++++++++ | ||
| 24 | 1 file changed, 11 insertions(+) | ||
| 25 | |||
| 26 | diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c | ||
| 27 | index 68bfa47568..1bcf803db6 100644 | ||
| 28 | --- a/hw/display/qxl-logger.c | ||
| 29 | +++ b/hw/display/qxl-logger.c | ||
| 30 | @@ -247,6 +247,16 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) | ||
| 31 | qxl_name(qxl_type, ext->cmd.type), | ||
| 32 | compat ? "(compat)" : ""); | ||
| 33 | |||
| 34 | + switch (ext->cmd.type) { | ||
| 35 | + case QXL_CMD_DRAW: | ||
| 36 | + break; | ||
| 37 | + case QXL_CMD_SURFACE: | ||
| 38 | + break; | ||
| 39 | + case QXL_CMD_CURSOR: | ||
| 40 | + break; | ||
| 41 | + default: | ||
| 42 | + goto out; | ||
| 43 | + } | ||
| 44 | data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); | ||
| 45 | if (!data) { | ||
| 46 | return 1; | ||
| 47 | @@ -269,6 +279,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) | ||
| 48 | qxl_log_cmd_cursor(qxl, data, ext->group_id); | ||
| 49 | break; | ||
| 50 | } | ||
| 51 | +out: | ||
| 52 | fprintf(stderr, "\n"); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | -- | ||
| 56 | 2.34.1 | ||
| 57 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch b/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch new file mode 100644 index 0000000000..ac51cf567a --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0001-hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | Upstream-Status: Backport [https://github.com/qemu/qemu/commit/8efec0e] | ||
| 2 | |||
| 3 | Backport and rebase patch to fix compile error which imported by CVE-2022-4144.patch: | ||
| 4 | |||
| 5 | ../qemu-6.2.0/hw/display/qxl.c: In function 'qxl_phys2virt': | ||
| 6 | ../qemu-6.2.0/hw/display/qxl.c:1477:67: error: 'size' undeclared (first use in this function); did you mean 'gsize'? | ||
| 7 | 1477 | if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) { | ||
| 8 | | ^~~~ | ||
| 9 | | gsize | ||
| 10 | ../qemu-6.2.0/hw/display/qxl.c:1477:67: note: each undeclared identifier is reported only once for each function it appears in | ||
| 11 | |||
| 12 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
| 13 | |||
| 14 | From 8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f Mon Sep 17 00:00:00 2001 | ||
| 15 | From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org> | ||
| 16 | Date: Mon, 28 Nov 2022 21:27:39 +0100 | ||
| 17 | Subject: [PATCH] hw/display/qxl: Pass requested buffer size to qxl_phys2virt() | ||
| 18 | MIME-Version: 1.0 | ||
| 19 | Content-Type: text/plain; charset=UTF-8 | ||
| 20 | Content-Transfer-Encoding: 8bit | ||
| 21 | |||
| 22 | Currently qxl_phys2virt() doesn't check for buffer overrun. | ||
| 23 | In order to do so in the next commit, pass the buffer size | ||
| 24 | as argument. | ||
| 25 | |||
| 26 | For QXLCursor in qxl_render_cursor() -> qxl_cursor() we | ||
| 27 | verify the size of the chunked data ahead, checking we can | ||
| 28 | access 'sizeof(QXLCursor) + chunk->data_size' bytes. | ||
| 29 | Since in the SPICE_CURSOR_TYPE_MONO case the cursor is | ||
| 30 | assumed to fit in one chunk, no change are required. | ||
| 31 | In SPICE_CURSOR_TYPE_ALPHA the ahead read is handled in | ||
| 32 | qxl_unpack_chunks(). | ||
| 33 | |||
| 34 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 35 | Acked-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 36 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
| 37 | Message-Id: <20221128202741.4945-4-philmd@linaro.org> | ||
| 38 | --- | ||
| 39 | hw/display/qxl-logger.c | 11 ++++++++--- | ||
| 40 | hw/display/qxl-render.c | 20 ++++++++++++++++---- | ||
| 41 | hw/display/qxl.c | 14 +++++++++----- | ||
| 42 | hw/display/qxl.h | 3 ++- | ||
| 43 | 4 files changed, 35 insertions(+), 13 deletions(-) | ||
| 44 | |||
| 45 | diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c | ||
| 46 | index 1bcf803..35c38f6 100644 | ||
| 47 | --- a/hw/display/qxl-logger.c | ||
| 48 | +++ b/hw/display/qxl-logger.c | ||
| 49 | @@ -106,7 +106,7 @@ static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id) | ||
| 50 | QXLImage *image; | ||
| 51 | QXLImageDescriptor *desc; | ||
| 52 | |||
| 53 | - image = qxl_phys2virt(qxl, addr, group_id); | ||
| 54 | + image = qxl_phys2virt(qxl, addr, group_id, sizeof(QXLImage)); | ||
| 55 | if (!image) { | ||
| 56 | return 1; | ||
| 57 | } | ||
| 58 | @@ -214,7 +214,8 @@ int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id) | ||
| 59 | cmd->u.set.position.y, | ||
| 60 | cmd->u.set.visible ? "yes" : "no", | ||
| 61 | cmd->u.set.shape); | ||
| 62 | - cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id); | ||
| 63 | + cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id, | ||
| 64 | + sizeof(QXLCursor)); | ||
| 65 | if (!cursor) { | ||
| 66 | return 1; | ||
| 67 | } | ||
| 68 | @@ -236,6 +237,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) | ||
| 69 | { | ||
| 70 | bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT; | ||
| 71 | void *data; | ||
| 72 | + size_t datasz; | ||
| 73 | int ret; | ||
| 74 | |||
| 75 | if (!qxl->cmdlog) { | ||
| 76 | @@ -249,15 +251,18 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) | ||
| 77 | |||
| 78 | switch (ext->cmd.type) { | ||
| 79 | case QXL_CMD_DRAW: | ||
| 80 | + datasz = compat ? sizeof(QXLCompatDrawable) : sizeof(QXLDrawable); | ||
| 81 | break; | ||
| 82 | case QXL_CMD_SURFACE: | ||
| 83 | + datasz = sizeof(QXLSurfaceCmd); | ||
| 84 | break; | ||
| 85 | case QXL_CMD_CURSOR: | ||
| 86 | + datasz = sizeof(QXLCursorCmd); | ||
| 87 | break; | ||
| 88 | default: | ||
| 89 | goto out; | ||
| 90 | } | ||
| 91 | - data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); | ||
| 92 | + data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, datasz); | ||
| 93 | if (!data) { | ||
| 94 | return 1; | ||
| 95 | } | ||
| 96 | diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c | ||
| 97 | index ca21700..fcfd40c 100644 | ||
| 98 | --- a/hw/display/qxl-render.c | ||
| 99 | +++ b/hw/display/qxl-render.c | ||
| 100 | @@ -107,7 +107,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) | ||
| 101 | qxl->guest_primary.resized = 0; | ||
| 102 | qxl->guest_primary.data = qxl_phys2virt(qxl, | ||
| 103 | qxl->guest_primary.surface.mem, | ||
| 104 | - MEMSLOT_GROUP_GUEST); | ||
| 105 | + MEMSLOT_GROUP_GUEST, | ||
| 106 | + qxl->guest_primary.abs_stride | ||
| 107 | + * height); | ||
| 108 | if (!qxl->guest_primary.data) { | ||
| 109 | goto end; | ||
| 110 | } | ||
| 111 | @@ -228,7 +230,8 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, | ||
| 112 | if (offset == size) { | ||
| 113 | return; | ||
| 114 | } | ||
| 115 | - chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id); | ||
| 116 | + chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id, | ||
| 117 | + sizeof(QXLDataChunk) + chunk->data_size); | ||
| 118 | if (!chunk) { | ||
| 119 | return; | ||
| 120 | } | ||
| 121 | @@ -295,7 +298,8 @@ fail: | ||
| 122 | /* called from spice server thread context only */ | ||
| 123 | int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) | ||
| 124 | { | ||
| 125 | - QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); | ||
| 126 | + QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, | ||
| 127 | + sizeof(QXLCursorCmd)); | ||
| 128 | QXLCursor *cursor; | ||
| 129 | QEMUCursor *c; | ||
| 130 | |||
| 131 | @@ -314,7 +318,15 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) | ||
| 132 | } | ||
| 133 | switch (cmd->type) { | ||
| 134 | case QXL_CURSOR_SET: | ||
| 135 | - cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id); | ||
| 136 | + /* First read the QXLCursor to get QXLDataChunk::data_size ... */ | ||
| 137 | + cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, | ||
| 138 | + sizeof(QXLCursor)); | ||
| 139 | + if (!cursor) { | ||
| 140 | + return 1; | ||
| 141 | + } | ||
| 142 | + /* Then read including the chunked data following QXLCursor. */ | ||
| 143 | + cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, | ||
| 144 | + sizeof(QXLCursor) + cursor->chunk.data_size); | ||
| 145 | if (!cursor) { | ||
| 146 | return 1; | ||
| 147 | } | ||
| 148 | diff --git a/hw/display/qxl.c b/hw/display/qxl.c | ||
| 149 | index ae8aa07..2a4b2d4 100644 | ||
| 150 | --- a/hw/display/qxl.c | ||
| 151 | +++ b/hw/display/qxl.c | ||
| 152 | @@ -274,7 +274,8 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) | ||
| 153 | QXL_IO_MONITORS_CONFIG_ASYNC)); | ||
| 154 | } | ||
| 155 | |||
| 156 | - cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST); | ||
| 157 | + cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST, | ||
| 158 | + sizeof(QXLMonitorsConfig)); | ||
| 159 | if (cfg != NULL && cfg->count == 1) { | ||
| 160 | qxl->guest_primary.resized = 1; | ||
| 161 | qxl->guest_head0_width = cfg->heads[0].width; | ||
| 162 | @@ -459,7 +460,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) | ||
| 163 | switch (le32_to_cpu(ext->cmd.type)) { | ||
| 164 | case QXL_CMD_SURFACE: | ||
| 165 | { | ||
| 166 | - QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); | ||
| 167 | + QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, | ||
| 168 | + sizeof(QXLSurfaceCmd)); | ||
| 169 | |||
| 170 | if (!cmd) { | ||
| 171 | return 1; | ||
| 172 | @@ -494,7 +496,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) | ||
| 173 | } | ||
| 174 | case QXL_CMD_CURSOR: | ||
| 175 | { | ||
| 176 | - QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); | ||
| 177 | + QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, | ||
| 178 | + sizeof(QXLCursorCmd)); | ||
| 179 | |||
| 180 | if (!cmd) { | ||
| 181 | return 1; | ||
| 182 | @@ -1463,7 +1466,8 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, | ||
| 183 | } | ||
| 184 | |||
| 185 | /* can be also called from spice server thread context */ | ||
| 186 | -void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id) | ||
| 187 | +void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id, | ||
| 188 | + size_t size) | ||
| 189 | { | ||
| 190 | uint64_t offset; | ||
| 191 | uint32_t slot; | ||
| 192 | @@ -1971,7 +1975,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) | ||
| 193 | } | ||
| 194 | |||
| 195 | cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i], | ||
| 196 | - MEMSLOT_GROUP_GUEST); | ||
| 197 | + MEMSLOT_GROUP_GUEST, sizeof(QXLSurfaceCmd)); | ||
| 198 | assert(cmd); | ||
| 199 | assert(cmd->type == QXL_SURFACE_CMD_CREATE); | ||
| 200 | qxl_dirty_one_surface(qxl, cmd->u.surface_create.data, | ||
| 201 | diff --git a/hw/display/qxl.h b/hw/display/qxl.h | ||
| 202 | index 30d21f4..4551c23 100644 | ||
| 203 | --- a/hw/display/qxl.h | ||
| 204 | +++ b/hw/display/qxl.h | ||
| 205 | @@ -147,7 +147,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL) | ||
| 206 | #define QXL_DEFAULT_REVISION (QXL_REVISION_STABLE_V12 + 1) | ||
| 207 | |||
| 208 | /* qxl.c */ | ||
| 209 | -void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); | ||
| 210 | +void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id, | ||
| 211 | + size_t size); | ||
| 212 | void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) | ||
| 213 | GCC_FMT_ATTR(2, 3); | ||
| 214 | |||
| 215 | -- | ||
| 216 | 2.34.1 | ||
| 217 | |||
