227
virtio_gpu_ctrl_response(g, cmd, &edid.hdr, sizeof(edid));
228
}
229
230
-static uint32_t calc_image_hostmem(pixman_format_code_t pformat,
231
- uint32_t width, uint32_t height)
230
+static bool calc_image_hostmem(pixman_format_code_t pformat,
231
+ uint32_t width, uint32_t height,
232
+ uint32_t *hostmem)
233
{
233
- /* Copied from pixman/pixman-bits-image.c, skip integer overflow check.
234
- * pixman_image_create_bits will fail in case it overflow.
235
- */
234
+ uint64_t bpp = PIXMAN_FORMAT_BPP(pformat);
235
+ uint64_t stride = (((uint64_t)width * bpp + 0x1f) >> 5) * sizeof(uint32_t);
236
+ uint64_t size = (uint64_t)height * stride;
237
237
- int bpp = PIXMAN_FORMAT_BPP(pformat);
238
- int stride = ((width * bpp + 0x1f) >> 5) * sizeof(uint32_t);
239
- return height * stride;
238
+ if (size > UINT32_MAX) {
239
+ return false;
240
+ }
241
+
242
+ *hostmem = size;
243
+ return true;
244
}
245
246
static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
250
pixman_format_code_t pformat;
251
struct virtio_gpu_simple_resource *res;
252
struct virtio_gpu_resource_create_2d c2d;
253
+ uint32_t hostmem;
254
255
VIRTIO_GPU_FILL_CMD(c2d);
256
virtio_gpu_bswap_32(&c2d, sizeof(c2d));
289
return;
290
}
291
287
- res->hostmem = calc_image_hostmem(pformat, c2d.width, c2d.height);
292
+ if (!calc_image_hostmem(pformat, c2d.width, c2d.height, &hostmem)) {
293
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: image dimensions overflow\n",
294
+ __func__);
295
+ goto end;
296
+ }
297
+ res->hostmem = hostmem;
298
if (res->hostmem + g->hostmem < g->conf_max_hostmem) {
299
if (!qemu_pixman_image_new_shareable(
300
&res->image,
1302
VirtIOGPU *g = opaque;
1303
Error *err = NULL;
1304
struct virtio_gpu_simple_resource *res;
1295
- uint32_t resource_id, pformat;
1305
+ uint32_t resource_id, pformat, hostmem;
1306
int i, ret;
1307
1308
g->hostmem = 0;
1328
return -EINVAL;
1329
}
1330
1321
- res->hostmem = calc_image_hostmem(pformat, res->width, res->height);
1331
+ if (!calc_image_hostmem(pformat, res->width, res->height, &hostmem)) {
1332
+ g_free(res);
1333
+ return -EINVAL;
1334
+ }
1335
+ res->hostmem = hostmem;
1336
if (!qemu_pixman_image_new_shareable(&res->image,
1337
&res->share_handle,
1338
"virtio-gpu res",