From nobody Fri Nov 21 10:10:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1762515701; cv=none; d=zohomail.com; s=zohoarc; b=T96/yCYZzLw47JBff/iOLLo6gx222voPESV93WG4ueqR/VQIR2A+PWQlHo33ZhsivijNhfQ+tdG9Fp72NfBUAYJHtQ4eDm3rbd/B+WuNx4JzND0WS3AB7qr/IAhrvmwQE3Cg6cM36A0QI8J6NqaER97tfvDA2vgRsA013okOpKM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1762515701; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=ljv77ArYkHP+nyXzGcXnoZRV32lj3ykU7WcevCkmNKQ=; b=oKbWNMrM+4lSanOOpw78VtM3bagVLqWm3fiLTmnc1w3+eH3ZQqXJMZ1lRG6O4rjdl1SEULYP6GJj5GTtQqFsA1gYWGK5D9/mlkVq5K8H9o+xP8PG7SKNS2mqfI2UuiYVmz8ckLzLSofNpuy5qESaXKSQ22FYBgbagR7HEaeVzJE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1762515701093343.35202550858867; Fri, 7 Nov 2025 03:41:41 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 7C4544184E; Fri, 7 Nov 2025 06:41:40 -0500 (EST) Received: from [172.19.199.29] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id F258F44B7D; Fri, 7 Nov 2025 06:30:18 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id EB1F144B0B; Fri, 7 Nov 2025 06:30:02 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id BE23E446A4 for ; Fri, 7 Nov 2025 06:26:48 -0500 (EST) Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-523-HjamKWcHNvuMNJ4lp6thQQ-1; Fri, 07 Nov 2025 06:26:47 -0500 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-427015f63faso250559f8f.0 for ; Fri, 07 Nov 2025 03:26:46 -0800 (PST) Received: from wheatley.localdomain ([85.93.96.130]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-42ac67920fcsm4775664f8f.39.2025.11.07.03.26.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Nov 2025 03:26:44 -0800 (PST) Received: from wheatley.pinto-pinecone.ts.net (wheatley.k8r.cz [127.0.0.1]) by wheatley.localdomain (Postfix) with ESMTP id 42557E161B5C; Fri, 07 Nov 2025 12:26:42 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762514808; 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=ljv77ArYkHP+nyXzGcXnoZRV32lj3ykU7WcevCkmNKQ=; b=iK/PX+yaT+zIZ/uej5dl8JONRr6U62Z6K3+WHnyjtBay7+/iOWtN/3rCKcRNMqspd/eoFN dF2nUmFC2C1JsWE7S22thsQPF1QCwYwSqUfrmzJ45/c3yW4xhKsm7KCdPtksgK1eknhg3N 8kYhJrFvOFeEq/5O6CG9m0/GgLWFj2Y= X-MC-Unique: HjamKWcHNvuMNJ4lp6thQQ-1 X-Mimecast-MFC-AGG-ID: HjamKWcHNvuMNJ4lp6thQQ_1762514806 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762514806; x=1763119606; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ljv77ArYkHP+nyXzGcXnoZRV32lj3ykU7WcevCkmNKQ=; b=q7wu+ZIfXJFKYv0AdbVlJoOUsGLIbd2M8PbczfU7cWptG3lVBT+YdKyJB/XUeT1CRc o2eunXLD5XCqXjT1DGzA0xkW8cTvLsF1yF5oIS9pOm2W9i0kASHIbgU3BszDCaw7IywQ 1FQ8VsyCPhHf9J/ysX9qUVroZyWC6bPgcgU0qGmTFfVPHDBBc4ntFXENDygfk+mwRw4O iQXekx8K+vQZfb5Ix9vFokZ7nd9lXv+XfIrk/vNQxDCcysY18u2FV38ugxpjLz06/o6i JzowVfrOna/iTXwlwandVpHqMJ2ELVzRGfAe0WW6brf9RtdCNQI6tFpcTBrTze9C9Jjf q75w== X-Gm-Message-State: AOJu0Yz8bXJcm0wkVoadSFKR8I0Hsd4Knhd9gmDvPsFe27ZHbDLHCDqi z+ZlBaUul9HA0KQWpOo4obFfsb0InLJQmfIhLF+58CJE0sYl23OxmHUPe4XhJn6KFpjKqIb1Jul ySkxhL4Ey+ezo2O4sIjAMFlfG+wnyczcb95eEtWZDMIyG5NqbRgYB1LfuWmg= X-Gm-Gg: ASbGnct/vdyrDMTBFVI+mHI4VP9oIHVBICetRHIjfO7ewN8coZPGSADeU29T/GfKSWN OzKWFZks5DwGp9h0X4lr+0FMQsOpgU6f/zRQbwsAI20zNkqcv24elproCRllcFs9ayA9+kxS+y/ E5hewmcjsGE/OLcFgk+yw0MvcH799HDciW+GlI51ZHr5qNKBme7cluS8m8vsk4PZspVKVCBqFoP 364rT5wA8oBp86bTflhErFa+bMPbFh0Yv3f2Q6LsQYislJ2Hhu0Lf6t8veCkXWec7F1oE+DkiUl 6UCcTDcur0FL7y2lFa6icqPzIHnIs1vl8E2ueByfziJE879JXZA3Q3lz2oAJ9TepX12fuXcTulz ZI4gED6E5 X-Received: by 2002:a05:6000:40ce:b0:429:cf03:8b2c with SMTP id ffacd0b85a97d-42ae5ac2311mr2737301f8f.29.1762514805858; Fri, 07 Nov 2025 03:26:45 -0800 (PST) X-Google-Smtp-Source: AGHT+IGnMa3TiflN9dIeq42syPqopNPvc+drps9PGhpHLHrp8Jx6wq4RF9U7PzHfC7HI0d1V0aaPqA== X-Received: by 2002:a05:6000:40ce:b0:429:cf03:8b2c with SMTP id ffacd0b85a97d-42ae5ac2311mr2737270f8f.29.1762514805391; Fri, 07 Nov 2025 03:26:45 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH 7/7] qemu: Check ACLs before parsing the whole domain XML Date: Fri, 7 Nov 2025 12:26:35 +0100 Message-ID: <6e1dc1c6a136c8431ab0c33dd96a4a8580e10cd3.1762514681.git.mkletzan@redhat.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 7mPlZYsclmiA736lVpUG2XcetG7eL7udAoQgDOEuAVk_1762514806 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID-Hash: BDJY4DZBXNSUXAI35ZS6U2LGW3KDSR2N X-Message-ID-Hash: BDJY4DZBXNSUXAI35ZS6U2LGW3KDSR2N X-MailFrom: mkletzan@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: =?UTF-8?q?=D0=A1=D0=B2=D1=8F=D1=82=D0=BE=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A2=D0=B5=D1=80=D0=B5=D1=88=D0=B8=D0=BD?= X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Martin Kletzander via Devel Reply-To: Martin Kletzander X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1762515702049154100 From: Martin Kletzander Utilise the new virDomainDefIDsParseString() for that. This is one of the more complex ones since there is also a function that reads relevant metadata from a save image XML. In order _not_ to extract the parsing out of the function (and make the function basically trivial and all callers more complex) add a callback to the function which will be used to check the ACLs. Fixes: CVE-2025-12748 Reported-by: =D0=A1=D0=B2=D1=8F=D1=82=D0=BE=D1=81=D0=BB=D0=B0=D0=B2 =D0=A2= =D0=B5=D1=80=D0=B5=D1=88=D0=B8=D0=BD Signed-off-by: Martin Kletzander --- src/qemu/qemu_driver.c | 90 ++++++++++++++++++++------------------- src/qemu/qemu_migration.c | 21 ++++++++- src/qemu/qemu_migration.h | 4 +- src/qemu/qemu_saveimage.c | 25 +++++++++-- src/qemu/qemu_saveimage.h | 4 +- src/qemu/qemu_snapshot.c | 4 +- 6 files changed, 95 insertions(+), 53 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a1b1edcbbf51..837935d524bc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1556,11 +1556,17 @@ static virDomainPtr qemuDomainCreateXML(virConnectP= tr conn, if (flags & VIR_DOMAIN_START_RESET_NVRAM) start_flags |=3D VIR_QEMU_PROCESS_START_RESET_NVRAM; =20 - if (!(def =3D virDomainDefParseString(xml, driver->xmlopt, - NULL, parse_flags))) - goto cleanup; + /* Avoid parsing the whole domain definition for ACL checks */ + if (!(def =3D virDomainDefIDsParseString(xml, driver->xmlopt, parse_fl= ags))) + return NULL; =20 if (virDomainCreateXMLEnsureACL(conn, def) < 0) + return NULL; + + g_clear_pointer(&def, virObjectUnref); + + if (!(def =3D virDomainDefParseString(xml, driver->xmlopt, + NULL, parse_flags))) goto cleanup; =20 if (!(vm =3D virDomainObjListAdd(driver->domains, &def, @@ -5780,7 +5786,7 @@ qemuDomainRestoreInternal(virConnectPtr conn, if (flags & VIR_DOMAIN_SAVE_RESET_NVRAM) reset_nvram =3D true; =20 - if (qemuSaveImageGetMetadata(driver, NULL, path, &def, &data) < 0) + if (qemuSaveImageGetMetadata(driver, NULL, path, ensureACL, conn, &def= , &data) < 0) goto cleanup; =20 sparse =3D data->header.format =3D=3D QEMU_SAVE_FORMAT_SPARSE; @@ -5793,9 +5799,6 @@ qemuDomainRestoreInternal(virConnectPtr conn, if (fd < 0) goto cleanup; =20 - if (ensureACL(conn, def) < 0) - goto cleanup; - if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { int hookret; =20 @@ -5923,10 +5926,9 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, co= nst char *path, =20 virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE, NULL); =20 - if (qemuSaveImageGetMetadata(driver, NULL, path, &def, &data) < 0) - goto cleanup; - - if (virDomainSaveImageGetXMLDescEnsureACL(conn, def) < 0) + if (qemuSaveImageGetMetadata(driver, NULL, path, + virDomainSaveImageGetXMLDescEnsureACL, + conn, &def, &data) < 0) goto cleanup; =20 ret =3D qemuDomainDefFormatXML(driver, NULL, def, flags); @@ -5956,7 +5958,9 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, cons= t char *path, else if (flags & VIR_DOMAIN_SAVE_PAUSED) state =3D 0; =20 - if (qemuSaveImageGetMetadata(driver, NULL, path, &def, &data) < 0) + if (qemuSaveImageGetMetadata(driver, NULL, path, + virDomainSaveImageDefineXMLEnsureACL, + conn, &def, &data) < 0) goto cleanup; =20 fd =3D qemuSaveImageOpen(driver, path, false, false, NULL, true); @@ -5964,9 +5968,6 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, cons= t char *path, if (fd < 0) goto cleanup; =20 - if (virDomainSaveImageDefineXMLEnsureACL(conn, def) < 0) - goto cleanup; - if (STREQ(data->xml, dxml) && (state < 0 || state =3D=3D data->header.was_running)) { /* no change to the XML */ @@ -6038,7 +6039,8 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, uns= igned int flags) goto cleanup; } =20 - if (qemuSaveImageGetMetadata(driver, priv->qemuCaps, path, &def, &data= ) < 0) + if (qemuSaveImageGetMetadata(driver, priv->qemuCaps, path, + NULL, NULL, &def, &data) < 0) goto cleanup; =20 ret =3D qemuDomainDefFormatXML(driver, priv->qemuCaps, def, flags); @@ -6102,7 +6104,7 @@ qemuDomainObjRestore(virConnectPtr conn, bool sparse =3D false; g_autoptr(qemuMigrationParams) restoreParams =3D NULL; =20 - ret =3D qemuSaveImageGetMetadata(driver, NULL, path, &def, &data); + ret =3D qemuSaveImageGetMetadata(driver, NULL, path, NULL, NULL, &def,= &data); if (ret < 0) { if (qemuSaveImageIsCorrupt(driver, path)) { if (unlink(path) < 0) { @@ -6464,6 +6466,15 @@ qemuDomainDefineXMLFlags(virConnectPtr conn, if (flags & VIR_DOMAIN_DEFINE_VALIDATE) parse_flags |=3D VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA; =20 + /* Avoid parsing the whole domain definition for ACL checks */ + if (!(def =3D virDomainDefIDsParseString(xml, driver->xmlopt, parse_fl= ags))) + return NULL; + + if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0) + return NULL; + + g_clear_pointer(&def, virObjectUnref); + if (!(def =3D virDomainDefParseString(xml, driver->xmlopt, NULL, parse_flags))) return NULL; @@ -6471,9 +6482,6 @@ qemuDomainDefineXMLFlags(virConnectPtr conn, if (virXMLCheckIllegalChars("name", def->name, "\n") < 0) goto cleanup; =20 - if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0) - goto cleanup; - if (!(vm =3D virDomainObjListAdd(driver->domains, &def, driver->xmlopt, 0, &oldDef))) @@ -10769,10 +10777,9 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, return -1; } =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepareTunnelEnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepareTunnelEn= sureACL))) return -1; =20 return qemuMigrationDstPrepareTunnel(driver, dconn, @@ -10822,10 +10829,9 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, return -1; } =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepare2EnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepare2EnsureA= CL))) return -1; =20 /* Do not use cookies in v2 protocol, since the cookie @@ -11045,10 +11051,9 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, QEMU_MIGRATION_DESTINAT= ION))) return -1; =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepare3EnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepare3EnsureA= CL))) return -1; =20 return qemuMigrationDstPrepareDirect(driver, dconn, @@ -11148,10 +11153,9 @@ qemuDomainMigratePrepare3Params(virConnectPtr dcon= n, return -1; } =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepare3ParamsEnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepare3ParamsE= nsureACL))) return -1; =20 return qemuMigrationDstPrepareDirect(driver, dconn, @@ -11193,10 +11197,9 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dcon= n, QEMU_MIGRATION_DESTINAT= ION))) return -1; =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepareTunnel3EnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepareTunnel3E= nsureACL))) return -1; =20 return qemuMigrationDstPrepareTunnel(driver, dconn, @@ -11245,10 +11248,9 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPt= r dconn, QEMU_MIGRATION_DESTINAT= ION))) return -1; =20 - if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname))) - return -1; - - if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn, def) < 0) + if (!(def =3D qemuMigrationAnyPrepareDef(driver, NULL, dom_xml, dname,= &origname, + dconn, + virDomainMigratePrepareTunnel3P= aramsEnsureACL))) return -1; =20 return qemuMigrationDstPrepareTunnel(driver, dconn, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 9109c4526db1..dcf9ea444ef9 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -4030,7 +4030,9 @@ qemuMigrationAnyPrepareDef(virQEMUDriver *driver, virQEMUCaps *qemuCaps, const char *dom_xml, const char *dname, - char **origname) + char **origname, + virConnectPtr sconn, + int (*ensureACL)(virConnectPtr, virDomainDef *)) { virDomainDef *def; char *name =3D NULL; @@ -4041,6 +4043,22 @@ qemuMigrationAnyPrepareDef(virQEMUDriver *driver, return NULL; } =20 + /* Avoid parsing the whole domain definition for ACL checks */ + if (!(def =3D virDomainDefIDsParseString(dom_xml, driver->xmlopt, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) + goto cleanup; + + if (dname) { + VIR_FREE(def->name); + def->name =3D g_strdup(dname); + } + + if (ensureACL && ensureACL(sconn, def) < 0) { + g_clear_pointer(&def, virObjectUnref); + goto cleanup; + } + g_clear_pointer(&def, virObjectUnref); + if (!(def =3D virDomainDefParseString(dom_xml, driver->xmlopt, qemuCaps, VIR_DOMAIN_DEF_PARSE_INACTIVE))) @@ -4969,6 +4987,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, if (!(persistDef =3D qemuMigrationAnyPrepareDef(driver, priv->qemuCaps, persist_xml, + NULL, NULL, NULL, NULL))) goto error; } else { diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 36865040dffc..50910ecb1f92 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -134,7 +134,9 @@ qemuMigrationAnyPrepareDef(virQEMUDriver *driver, virQEMUCaps *qemuCaps, const char *dom_xml, const char *dname, - char **origname); + char **origname, + virConnectPtr sconn, + int (*ensureACL)(virConnectPtr, virDomainDef *)= ); =20 int qemuMigrationDstPrepareTunnel(virQEMUDriver *driver, diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index aa030798ce19..145a0f483283 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -614,16 +614,21 @@ qemuSaveImageIsCorrupt(virQEMUDriver *driver, const c= har *path) * @driver: qemu driver data * @qemuCaps: pointer to qemuCaps if the domain is running or NULL * @path: path of the save image + * @ensureACL: ACL callback to check against the definition or NULL + * @conn: parameter for the @ensureACL callback * @ret_def: returns domain definition created from the XML stored in the = image * @ret_data: returns structure filled with data from the image header * - * Open the save image file, read libvirt's save image metadata, and popul= ate - * the @ret_def and @ret_data structures. Returns 0 on success and -1 on f= ailure. + * Open the save image file, read libvirt's save image metadata, optionally + * check ACLs before parsing the whole domain definition and populate the + * @ret_def and @ret_data structures. Returns 0 on success and -1 on failu= re. */ int qemuSaveImageGetMetadata(virQEMUDriver *driver, virQEMUCaps *qemuCaps, const char *path, + int (*ensureACL)(virConnectPtr, virDomainDef *), + virConnectPtr conn, virDomainDef **ret_def, virQEMUSaveData **ret_data) { @@ -631,6 +636,8 @@ qemuSaveImageGetMetadata(virQEMUDriver *driver, VIR_AUTOCLOSE fd =3D -1; virQEMUSaveData *data; g_autoptr(virDomainDef) def =3D NULL; + unsigned int parse_flags =3D VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE; int rc; =20 if ((fd =3D qemuDomainOpenFile(cfg, NULL, path, O_RDONLY, NULL)) < 0) @@ -640,10 +647,20 @@ qemuSaveImageGetMetadata(virQEMUDriver *driver, return rc; =20 data =3D *ret_data; + + if (ensureACL) { + /* Parse only the IDs for ACL checks */ + g_autoptr(virDomainDef) aclDef =3D virDomainDefIDsParseString(data= ->xml, + driver= ->xmlopt, + parse_= flags); + + if (!aclDef || ensureACL(conn, aclDef) < 0) + return -1; + } + /* Create a domain from this XML */ if (!(def =3D virDomainDefParseString(data->xml, driver->xmlopt, qemuC= aps, - VIR_DOMAIN_DEF_PARSE_INACTIVE | - VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE= ))) + parse_flags))) return -1; =20 *ret_def =3D g_steal_pointer(&def); diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h index 89c694138505..15b73eb39575 100644 --- a/src/qemu/qemu_saveimage.h +++ b/src/qemu/qemu_saveimage.h @@ -98,9 +98,11 @@ int qemuSaveImageGetMetadata(virQEMUDriver *driver, virQEMUCaps *qemuCaps, const char *path, + int (*ensureACL)(virConnectPtr, virDomainDef *), + virConnectPtr conn, virDomainDef **ret_def, virQEMUSaveData **ret_data) - ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); + ATTRIBUTE_NONNULL(6) ATTRIBUTE_NONNULL(7); =20 int qemuSaveImageOpen(virQEMUDriver *driver, diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index d4994dd54ed7..5aa7d1b3a79d 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -2486,8 +2486,8 @@ qemuSnapshotRevertExternalPrepare(virDomainObj *vm, g_autoptr(virDomainDef) savedef =3D NULL; =20 memdata->path =3D snapdef->memorysnapshotfile; - if (qemuSaveImageGetMetadata(driver, NULL, memdata->path, &savedef, - &memdata->data) < 0) + if (qemuSaveImageGetMetadata(driver, NULL, memdata->path, NULL, NU= LL, + &savedef, &memdata->data) < 0) return -1; =20 memdata->fd =3D qemuSaveImageOpen(driver, memdata->path, --=20 2.51.2