From nobody Tue Apr 7 00:01:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1773768088; cv=none; d=zohomail.com; s=zohoarc; b=MMQEwX84lIj65Ch9JPhKxZdnOiNa13lTothsDU+D4Eh9rYukIuTqnFxK53ntu0Ed6NBOmMJuWbi/qTGWxd9JlrUstOUW/Ilu5wWyhbZyGxWUuNpD/8SUZkUSe2/r4htPHy2svotm3XlM2cXk3fvC+kS0OtBvl/arvAfxjSxhFDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773768088; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=8h0sizqDRrWh4i0kVqCLWnQ1yrxi4rvEkqw6RMr/1k4=; b=VK/2ckrVnBMpSvjosWQ5YV3A+AsnDjxdz5/1O4h4vM6xRozqDJ+n3TzhDsWbypGfQgtJXtbJEI2EQF2F9v3wyOT/UlXSzilN0qOIxLhjYeR3nWZAX62yC1EKMqO+LsgkSfXKvssV0WKOcvVhunOAOzwCB8JfA8cPs1m/mJ0XzrQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1773768088930817.2490006092911; Tue, 17 Mar 2026 10:21:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w2Y5K-00020J-Pm; Tue, 17 Mar 2026 13:20:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w2Y5F-0001yd-Px for qemu-devel@nongnu.org; Tue, 17 Mar 2026 13:19:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w2Y5E-0005MF-Be for qemu-devel@nongnu.org; Tue, 17 Mar 2026 13:19:57 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-473-BMVKYw-lP2yzcljQnT6FrA-1; Tue, 17 Mar 2026 13:19:52 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DECE118005BD; Tue, 17 Mar 2026 17:19:50 +0000 (UTC) Received: from localhost (unknown [10.44.22.4]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8B6721800576; Tue, 17 Mar 2026 17:19:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773767994; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8h0sizqDRrWh4i0kVqCLWnQ1yrxi4rvEkqw6RMr/1k4=; b=ekEYlOU6GhXU888HtJ//HzJOYZaw2QMwif5Rm+MzvdTJBUu1nOYZurH8ePRaceJhO8Zd81 /5+nNHnO2f8j6vFj9Qg5iRyXPG0+ltjGNVLCPTmHxd4AfTPSkBBG4rAp+dm5/QIpSTn7Gq WRhI2lRC+4gHm0Y/YIiJS5lCu3AWrtg= X-MC-Unique: BMVKYw-lP2yzcljQnT6FrA-1 X-Mimecast-MFC-AGG-ID: BMVKYw-lP2yzcljQnT6FrA_1773767991 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Dmitry Osipenko , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , "Michael S. Tsirkin" , Christian Schoenebeck , Ani Sinha , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Gerd Hoffmann , Zhao Liu , Marcel Apfelbaum , Yanan Wang , Akihiko Odaki Subject: [PULL 04/16] virtio-gpu: fix overflow check when allocating 2d image Date: Tue, 17 Mar 2026 21:19:04 +0400 Message-ID: <20260317171916.438575-5-marcandre.lureau@redhat.com> In-Reply-To: <20260317171916.438575-1-marcandre.lureau@redhat.com> References: <20260317171916.438575-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1773768091039158500 From: Marc-Andr=C3=A9 Lureau The calc_image_hostmem() comment says pixman_image_create_bits() checks for overflow. However, this relied on the facts that "bits" was NULL and it performed it when it was introduced. Since commit 9462ff4695aa, the "bits" argument can be provided and the check is no longer applied. Promotes the computation to uint64_t and adds an explicit overflow check to avoid potential later OOB read/write on the image data. Fixes: CVE-2026-3886 Fixes: ZDI-CAN-27578 Fixes: 9462ff4695aa ("virtio-gpu/win32: allocate shareable 2d resources/ima= ges") Reported-by: Zero Day Initiative Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Akihiko Odaki Message-Id: <20260311-cve-v1-1-f72b4c7c1ab2@redhat.com> --- hw/display/virtio-gpu.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index de7a86a73d2..468ea6ab0fb 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -227,16 +227,20 @@ void virtio_gpu_get_edid(VirtIOGPU *g, virtio_gpu_ctrl_response(g, cmd, &edid.hdr, sizeof(edid)); } =20 -static uint32_t calc_image_hostmem(pixman_format_code_t pformat, - uint32_t width, uint32_t height) +static bool calc_image_hostmem(pixman_format_code_t pformat, + uint32_t width, uint32_t height, + uint32_t *hostmem) { - /* Copied from pixman/pixman-bits-image.c, skip integer overflow check. - * pixman_image_create_bits will fail in case it overflow. - */ + uint64_t bpp =3D PIXMAN_FORMAT_BPP(pformat); + uint64_t stride =3D (((uint64_t)width * bpp + 0x1f) >> 5) * sizeof(uin= t32_t); + uint64_t size =3D (uint64_t)height * stride; =20 - int bpp =3D PIXMAN_FORMAT_BPP(pformat); - int stride =3D ((width * bpp + 0x1f) >> 5) * sizeof(uint32_t); - return height * stride; + if (size > UINT32_MAX) { + return false; + } + + *hostmem =3D size; + return true; } =20 static void virtio_gpu_resource_create_2d(VirtIOGPU *g, @@ -246,6 +250,7 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g, pixman_format_code_t pformat; struct virtio_gpu_simple_resource *res; struct virtio_gpu_resource_create_2d c2d; + uint32_t hostmem; =20 VIRTIO_GPU_FILL_CMD(c2d); virtio_gpu_bswap_32(&c2d, sizeof(c2d)); @@ -284,7 +289,12 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g, return; } =20 - res->hostmem =3D calc_image_hostmem(pformat, c2d.width, c2d.height); + if (!calc_image_hostmem(pformat, c2d.width, c2d.height, &hostmem)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: image dimensions overflow\n", + __func__); + goto end; + } + res->hostmem =3D hostmem; if (res->hostmem + g->hostmem < g->conf_max_hostmem) { if (!qemu_pixman_image_new_shareable( &res->image, @@ -1292,7 +1302,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque,= size_t size, VirtIOGPU *g =3D opaque; Error *err =3D NULL; struct virtio_gpu_simple_resource *res; - uint32_t resource_id, pformat; + uint32_t resource_id, pformat, hostmem; int i, ret; =20 g->hostmem =3D 0; @@ -1318,7 +1328,11 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque= , size_t size, return -EINVAL; } =20 - res->hostmem =3D calc_image_hostmem(pformat, res->width, res->heig= ht); + if (!calc_image_hostmem(pformat, res->width, res->height, &hostmem= )) { + g_free(res); + return -EINVAL; + } + res->hostmem =3D hostmem; if (!qemu_pixman_image_new_shareable(&res->image, &res->share_handle, "virtio-gpu res", --=20 2.53.0