From nobody Wed May 15 20:00:21 2024 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=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1695129673; cv=none; d=zohomail.com; s=zohoarc; b=Z8AuXj7ymwGiVNOL79c5EPBhDdfuDLtfSv7LQkWEcRMZ0iBRX+SssB2Nyd7d9PuPEDjB0zALziR8hwc0sD69AKfURbE81zODQ3irekPSzoRs0ssNss5VK1NetrQJVvT0NVMcE52Ekow8Tt8291hADZXr6Oi6jU1AJhGCI5631YA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695129673; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=qETdIitbhf/BthXK2sakRD0VMASLyjOh0xXZhbeiKns=; b=esr2pMXS1CefcNUX1fAELSUN/0+tI2hdF0q0veesUgtrQePchy1ccEqdFyn4p/Vg/SLdBU60O0aWvWOrGzfxuIIhBVC2SEckknf6s+TscQO8IZHaVrKzEJHrNrGXBKhr69XD6gBODat3lBCVRCimbzRwrtFF1w3IWIp24HUnJ2c= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1695129673409976.4691719699435; Tue, 19 Sep 2023 06:21:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qiaeF-0002Bo-0V; Tue, 19 Sep 2023 09:20:17 -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 1qiae5-0002Aq-U4 for qemu-devel@nongnu.org; Tue, 19 Sep 2023 09:20:07 -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 1qiae2-00037i-Hl for qemu-devel@nongnu.org; Tue, 19 Sep 2023 09:20:04 -0400 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-103-8hiz4OS1MZqck4r63jICIQ-1; Tue, 19 Sep 2023 09:19:58 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 41AC196742C; Tue, 19 Sep 2023 13:19:58 +0000 (UTC) Received: from lacos-laptop-9.usersys.redhat.com (unknown [10.39.192.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B1BA2156A27; Tue, 19 Sep 2023 13:19:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1695129601; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=qETdIitbhf/BthXK2sakRD0VMASLyjOh0xXZhbeiKns=; b=ZyEy0FboSpQYweQZz3ME6S7BXk1ypOj4Wh5z0kcz/NQuBXE0prG//29r1ws+88H8nkJTw1 Y4hLg4g1BMTURARKcl2z2acoe9nVMZXsWBzH2RE8hb3MFv13vBB8DOrPNAVTkOqZUmT/x5 jvE5UgJTpEJB0vNKX7atiYRu3bcgvi0= X-MC-Unique: 8hiz4OS1MZqck4r63jICIQ-1 From: Laszlo Ersek To: qemu-devel@nongnu.org, lersek@redhat.com Cc: Gerd Hoffmann , qemu-stable@nongnu.org Subject: [PATCH] hw/display/ramfb: plug slight guest-triggerable leak on mode setting Date: Tue, 19 Sep 2023 15:19:55 +0200 Message-Id: <20230919131955.27223-1-lersek@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 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=lersek@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, MIME_BASE64_TEXT=1.741, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1695129675226100005 Content-Type: text/plain; charset="utf-8" The fw_cfg DMA write callback in ramfb prepares a new display surface in QEMU; this new surface is put to use ("swapped in") upon the next display update. At that time, the old surface (if any) is released. If the guest triggers the fw_cfg DMA write callback at least twice between two adjacent display updates, then the second callback (and further such callbacks) will leak the previously prepared (but not yet swapped in) display surface. The issue can be shown by: (1) starting QEMU with "-trace displaysurface_free", and (2) running the following program in the guest UEFI shell: > #include // ShellAppMain() > #include // gBS > #include // EFI_GRAPHICS_OUTPUT_PROT= OCOL > > INTN > EFIAPI > ShellAppMain ( > IN UINTN Argc, > IN CHAR16 **Argv > ) > { > EFI_STATUS Status; > VOID *Interface; > EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; > UINT32 Mode; > > Status =3D gBS->LocateProtocol ( > &gEfiGraphicsOutputProtocolGuid, > NULL, > &Interface > ); > if (EFI_ERROR (Status)) { > return 1; > } > > Gop =3D Interface; > > Mode =3D 1; > for ( ; ;) { > Status =3D Gop->SetMode (Gop, Mode); > if (EFI_ERROR (Status)) { > break; > } > > Mode =3D 1 - Mode; > } > > return 1; > } The symptom is then that: - only one trace message appears periodically, - the time between adjacent messages keeps increasing -- implying that some list structure (containing the leaked resources) keeps growing, - the "surface" pointer is ever different. > 18566@1695127471.449586:displaysurface_free surface=3D0x7f2fcc09a7c0 > 18566@1695127471.529559:displaysurface_free surface=3D0x7f2fcc9dac10 > 18566@1695127471.659812:displaysurface_free surface=3D0x7f2fcc441dd0 > 18566@1695127471.839669:displaysurface_free surface=3D0x7f2fcc0363d0 > 18566@1695127472.069674:displaysurface_free surface=3D0x7f2fcc413a80 > 18566@1695127472.349580:displaysurface_free surface=3D0x7f2fcc09cd00 > 18566@1695127472.679783:displaysurface_free surface=3D0x7f2fcc1395f0 > 18566@1695127473.059848:displaysurface_free surface=3D0x7f2fcc1cae50 > 18566@1695127473.489724:displaysurface_free surface=3D0x7f2fcc42fc50 > 18566@1695127473.969791:displaysurface_free surface=3D0x7f2fcc45dcc0 > 18566@1695127474.499708:displaysurface_free surface=3D0x7f2fcc70b9d0 > 18566@1695127475.079769:displaysurface_free surface=3D0x7f2fcc82acc0 > 18566@1695127475.709941:displaysurface_free surface=3D0x7f2fcc369c00 > 18566@1695127476.389619:displaysurface_free surface=3D0x7f2fcc32b910 > 18566@1695127477.119772:displaysurface_free surface=3D0x7f2fcc0d5a20 > 18566@1695127477.899517:displaysurface_free surface=3D0x7f2fcc086c40 > 18566@1695127478.729962:displaysurface_free surface=3D0x7f2fccc72020 > 18566@1695127479.609839:displaysurface_free surface=3D0x7f2fcc185160 > 18566@1695127480.539688:displaysurface_free surface=3D0x7f2fcc23a7e0 > 18566@1695127481.519759:displaysurface_free surface=3D0x7f2fcc3ec870 > 18566@1695127482.549930:displaysurface_free surface=3D0x7f2fcc634960 > 18566@1695127483.629661:displaysurface_free surface=3D0x7f2fcc26b140 > 18566@1695127484.759987:displaysurface_free surface=3D0x7f2fcc321700 > 18566@1695127485.940289:displaysurface_free surface=3D0x7f2fccaad100 We figured this wasn't a CVE-worthy problem, as only small amounts of memory were leaked (the framebuffer itself is mapped from guest RAM, QEMU only allocates administrative structures), plus libvirt restricts QEMU memory footprint anyway, thus the guest can only DoS itself. Plug the leak, by releasing the last prepared (not yet swapped in) display surface, if any, in the fw_cfg DMA write callback. Regarding the "reproducer", with the fix in place, the log is flooded with trace messages (one per fw_cfg write), *and* the trace message alternates between just two "surface" pointer values (i.e., nothing is leaked, the allocator flip-flops between two objects in effect). This issue appears to date back to the introducion of ramfb (995b30179bdc, "hw/display: add ramfb, a simple boot framebuffer living in guest ram", 2018-06-18). Cc: Gerd Hoffmann (maintainer:ramfb) Cc: qemu-stable@nongnu.org Fixes: 995b30179bdc Signed-off-by: Laszlo Ersek Acked-by: Laszlo Ersek Reviewed-by: Gerd Hoffmann Reviewed-by: Marc-Andr=C3=A9 Lureau --- hw/display/ramfb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index 79b9754a5820..c2b002d53480 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -97,6 +97,7 @@ static void ramfb_fw_cfg_write(void *dev, off_t offset, s= ize_t len) =20 s->width =3D width; s->height =3D height; + qemu_free_displaysurface(s->ds); s->ds =3D surface; } =20