From nobody Sun May 12 14:19:14 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1699460696896866.7439099664666; Wed, 8 Nov 2023 08:24:56 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id CAE4319F7; Wed, 8 Nov 2023 11:24:53 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 5737F1967; Wed, 8 Nov 2023 11:24:21 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 0941219F5; Wed, 8 Nov 2023 11:24:05 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 0E1881967 for ; Wed, 8 Nov 2023 11:24:01 -0500 (EST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-169-RFuL5o2CPT6IERgRxOw7Fw-1; Wed, 08 Nov 2023 11:23:59 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 873518D26FF for ; Wed, 8 Nov 2023 16:23:59 +0000 (UTC) Received: from toolbox.redhat.com (unknown [10.42.28.56]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9B3A81C060AE; Wed, 8 Nov 2023 16:23:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-MC-Unique: RFuL5o2CPT6IERgRxOw7Fw-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [libvirt PATCH] src: reject empty string for 'dname' in migrate APIs Date: Wed, 8 Nov 2023 16:23:57 +0000 Message-ID: <20231108162357.1792115-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: BGU5MYOWCVNM7UT7FHWTNC42TW5MZL6V X-Message-ID-Hash: BGU5MYOWCVNM7UT7FHWTNC42TW5MZL6V X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1699460698248100001 A domain name is expected to be non-empty, and we validate this when parsing XML, or accepting a new name during renames. We fail to enforce this property, however, when performing a migration. This was discovered when a user complained about inaccessible VMs after migrating with the Rust APIs which mistakenly hardcoded 'dname' to the empty string. Fixes: https://gitlab.com/libvirt/libvirt-rust/-/issues/11 Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Jiri Denemark --- src/internal.h | 14 +++++++ src/libvirt-domain.c | 97 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/internal.h b/src/internal.h index 5a9e1c7cd0..01860efad9 100644 --- a/src/internal.h +++ b/src/internal.h @@ -441,6 +441,20 @@ goto label; \ } \ } while (0) +#define virCheckNonEmptyOptStringArgGoto(argname, label) \ + do { \ + if (argname && *argname =3D=3D '\0') { \ + virReportInvalidEmptyStringArg(argname); \ + goto label; \ + } \ + } while (0) +#define virCheckNonEmptyOptStringArgReturn(argname, retval) \ + do { \ + if (argname && *argname =3D=3D '\0') { \ + virReportInvalidEmptyStringArg(argname); \ + return retval; \ + } \ + } while (0) #define virCheckPositiveArgGoto(argname, label) \ do { \ if (argname <=3D 0) { \ diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 58e1e5ea8d..77a9682ecb 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -2991,6 +2991,8 @@ virDomainMigrateVersion1(virDomainPtr domain, "dconn=3D%p, flags=3D0x%lx, dname=3D%s, uri=3D%s, ban= dwidth=3D%lu", dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth= ); =20 + virCheckNonEmptyOptStringArgReturn(dname, NULL); + ret =3D virDomainGetInfo(domain, &info); if (ret =3D=3D 0 && info.state =3D=3D VIR_DOMAIN_PAUSED) flags |=3D VIR_MIGRATE_PAUSED; @@ -3085,6 +3087,8 @@ virDomainMigrateVersion2(virDomainPtr domain, "dconn=3D%p, flags=3D0x%lx, dname=3D%s, uri=3D%s, ban= dwidth=3D%lu", dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth= ); =20 + virCheckNonEmptyOptStringArgReturn(dname, NULL); + /* Prepare the migration. * * The destination host may return a cookie, or leave cookie as @@ -3242,6 +3246,8 @@ virDomainMigrateVersion3Full(virDomainPtr domain, bandwidth, params, nparams, useParams, flags); VIR_TYPED_PARAMS_DEBUG(params, nparams); =20 + virCheckNonEmptyOptStringArgReturn(dname, NULL); + if ((!useParams && (!domain->conn->driver->domainMigrateBegin3 || !domain->conn->driver->domainMigratePerform3 || @@ -3582,6 +3588,8 @@ virDomainMigrateUnmanagedProto2(virDomainPtr domain, return -1; } =20 + virCheckNonEmptyOptStringArgReturn(dname, -1); + if (flags & VIR_MIGRATE_PEER2PEER) { if (miguri) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3632,6 +3640,8 @@ virDomainMigrateUnmanagedProto3(virDomainPtr domain, return -1; } =20 + virCheckNonEmptyOptStringArgReturn(dname, -1); + return domain->conn->driver->domainMigratePerform3 (domain, xmlin, NULL, 0, NULL, NULL, dconnuri, miguri, flags, dname, bandwidth); @@ -3802,6 +3812,8 @@ virDomainMigrate(virDomainPtr domain, virCheckConnectGoto(dconn, error); virCheckReadOnlyGoto(dconn->flags, error); =20 + virCheckNonEmptyOptStringArgReturn(dname, NULL); + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_NON_SHARED_DISK, VIR_MIGRATE_NON_SHARED_INC, error); @@ -3999,6 +4011,8 @@ virDomainMigrate2(virDomainPtr domain, virCheckConnectGoto(dconn, error); virCheckReadOnlyGoto(dconn->flags, error); =20 + virCheckNonEmptyOptStringArgReturn(dname, NULL); + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_NON_SHARED_DISK, VIR_MIGRATE_NON_SHARED_INC, error); @@ -4232,6 +4246,19 @@ virDomainMigrate3(virDomainPtr domain, goto error; } =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_URI, &uri) < 0 || + virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 || + virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) <= 0) { + goto error; + } + + virCheckNonEmptyOptStringArgReturn(dname, NULL); + if (flags & VIR_MIGRATE_OFFLINE) { rc =3D VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn, VIR_DRV_FEATURE_MIGRATION_OFFLINE); @@ -4293,17 +4320,6 @@ virDomainMigrate3(virDomainPtr domain, goto error; } =20 - if (virTypedParamsGetString(params, nparams, - VIR_MIGRATE_PARAM_URI, &uri) < 0 || - virTypedParamsGetString(params, nparams, - VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 || - virTypedParamsGetString(params, nparams, - VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 || - virTypedParamsGetULLong(params, nparams, - VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) <= 0) { - goto error; - } - rc_src =3D VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn, VIR_DRV_FEATURE_MIGRATION_V3); if (rc_src < 0) @@ -4475,6 +4491,7 @@ virDomainMigrateToURI(virDomainPtr domain, virCheckDomainReturn(domain, -1); virCheckReadOnlyGoto(domain->conn->flags, error); virCheckNonNullArgGoto(duri, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED, VIR_MIGRATE_PARALLEL, @@ -4554,6 +4571,8 @@ virDomainMigrateToURI2(virDomainPtr domain, virCheckDomainReturn(domain, -1); virCheckReadOnlyGoto(domain->conn->flags, error); =20 + virCheckNonEmptyOptStringArgGoto(dname, error); + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED, VIR_MIGRATE_PARALLEL, error); @@ -4679,6 +4698,7 @@ virDomainMigratePrepare(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, -1); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigratePrepare) { int ret; @@ -4723,6 +4743,7 @@ virDomainMigratePerform(virDomainPtr domain, conn =3D domain->conn; =20 virCheckReadOnlyGoto(conn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (conn->driver->domainMigratePerform) { int ret; @@ -4762,6 +4783,7 @@ virDomainMigrateFinish(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, NULL); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigrateFinish) { virDomainPtr ret; @@ -4805,6 +4827,7 @@ virDomainMigratePrepare2(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, -1); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigratePrepare2) { int ret; @@ -4846,6 +4869,7 @@ virDomainMigrateFinish2(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, NULL); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigrateFinish2) { virDomainPtr ret; @@ -4886,6 +4910,7 @@ virDomainMigratePrepareTunnel(virConnectPtr conn, =20 virCheckConnectReturn(conn, -1); virCheckReadOnlyGoto(conn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (conn !=3D st->conn) { virReportInvalidArg(conn, "%s", @@ -4936,6 +4961,7 @@ virDomainMigrateBegin3(virDomainPtr domain, conn =3D domain->conn; =20 virCheckReadOnlyGoto(conn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (conn->driver->domainMigrateBegin3) { char *xml; @@ -4983,6 +5009,7 @@ virDomainMigratePrepare3(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, -1); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigratePrepare3) { int ret; @@ -5031,6 +5058,7 @@ virDomainMigratePrepareTunnel3(virConnectPtr conn, =20 virCheckConnectReturn(conn, -1); virCheckReadOnlyGoto(conn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (conn !=3D st->conn) { virReportInvalidArg(conn, "%s", @@ -5089,6 +5117,7 @@ virDomainMigratePerform3(virDomainPtr domain, conn =3D domain->conn; =20 virCheckReadOnlyGoto(conn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (conn->driver->domainMigratePerform3) { int ret; @@ -5135,6 +5164,7 @@ virDomainMigrateFinish3(virConnectPtr dconn, =20 virCheckConnectReturn(dconn, NULL); virCheckReadOnlyGoto(dconn->flags, error); + virCheckNonEmptyOptStringArgGoto(dname, error); =20 if (dconn->driver->domainMigrateFinish3) { virDomainPtr ret; @@ -5211,6 +5241,7 @@ virDomainMigrateBegin3Params(virDomainPtr domain, unsigned int flags) { virConnectPtr conn; + const char *dname =3D NULL; =20 VIR_DOMAIN_DEBUG(domain, "params=3D%p, nparams=3D%d, " "cookieout=3D%p, cookieoutlen=3D%p, flags=3D0x%x", @@ -5224,6 +5255,12 @@ virDomainMigrateBegin3Params(virDomainPtr domain, =20 virCheckReadOnlyGoto(conn->flags, error); =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (conn->driver->domainMigrateBegin3Params) { char *xml; xml =3D conn->driver->domainMigrateBegin3Params(domain, params, np= arams, @@ -5258,6 +5295,8 @@ virDomainMigratePrepare3Params(virConnectPtr dconn, char **uri_out, unsigned int flags) { + const char *dname =3D NULL; + VIR_DEBUG("dconn=3D%p, params=3D%p, nparams=3D%d, cookiein=3D%p, cooki= einlen=3D%d, " "cookieout=3D%p, cookieoutlen=3D%p, uri_out=3D%p, flags=3D0x= %x", dconn, params, nparams, cookiein, cookieinlen, @@ -5269,6 +5308,12 @@ virDomainMigratePrepare3Params(virConnectPtr dconn, virCheckConnectReturn(dconn, -1); virCheckReadOnlyGoto(dconn->flags, error); =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (dconn->driver->domainMigratePrepare3Params) { int ret; ret =3D dconn->driver->domainMigratePrepare3Params(dconn, params, = nparams, @@ -5303,6 +5348,8 @@ virDomainMigratePrepareTunnel3Params(virConnectPtr co= nn, int *cookieoutlen, unsigned int flags) { + const char *dname =3D NULL; + VIR_DEBUG("conn=3D%p, stream=3D%p, params=3D%p, nparams=3D%d, cookiein= =3D%p, " "cookieinlen=3D%d, cookieout=3D%p, cookieoutlen=3D%p, flags= =3D0x%x", conn, st, params, nparams, cookiein, cookieinlen, @@ -5320,6 +5367,12 @@ virDomainMigratePrepareTunnel3Params(virConnectPtr c= onn, goto error; } =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (conn->driver->domainMigratePrepareTunnel3Params) { int rv; rv =3D conn->driver->domainMigratePrepareTunnel3Params( @@ -5354,6 +5407,7 @@ virDomainMigratePerform3Params(virDomainPtr domain, unsigned int flags) { virConnectPtr conn; + const char *dname =3D NULL; =20 VIR_DOMAIN_DEBUG(domain, "dconnuri=3D%s, params=3D%p, nparams=3D%d, co= okiein=3D%p, " "cookieinlen=3D%d, cookieout=3D%p, cookieoutlen=3D%p,= flags=3D0x%x", @@ -5368,6 +5422,12 @@ virDomainMigratePerform3Params(virDomainPtr domain, =20 virCheckReadOnlyGoto(conn->flags, error); =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (conn->driver->domainMigratePerform3Params) { int ret; ret =3D conn->driver->domainMigratePerform3Params( @@ -5401,6 +5461,8 @@ virDomainMigrateFinish3Params(virConnectPtr dconn, unsigned int flags, int cancelled) { + const char *dname =3D NULL; + VIR_DEBUG("dconn=3D%p, params=3D%p, nparams=3D%d, cookiein=3D%p, cooki= einlen=3D%d, " "cookieout=3D%p, cookieoutlen=3D%p, flags=3D0x%x, cancelled= =3D%d", dconn, params, nparams, cookiein, cookieinlen, cookieout, @@ -5412,6 +5474,12 @@ virDomainMigrateFinish3Params(virConnectPtr dconn, virCheckConnectReturn(dconn, NULL); virCheckReadOnlyGoto(dconn->flags, error); =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (dconn->driver->domainMigrateFinish3Params) { virDomainPtr ret; ret =3D dconn->driver->domainMigrateFinish3Params( @@ -5444,6 +5512,7 @@ virDomainMigrateConfirm3Params(virDomainPtr domain, int cancelled) { virConnectPtr conn; + const char *dname =3D NULL; =20 VIR_DOMAIN_DEBUG(domain, "params=3D%p, nparams=3D%d, cookiein=3D%p, " "cookieinlen=3D%d, flags=3D0x%x, cancelled=3D%d", @@ -5457,6 +5526,12 @@ virDomainMigrateConfirm3Params(virDomainPtr domain, =20 virCheckReadOnlyGoto(conn->flags, error); =20 + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0) + goto error; + + virCheckNonEmptyOptStringArgGoto(dname, error); + if (conn->driver->domainMigrateConfirm3Params) { int ret; ret =3D conn->driver->domainMigrateConfirm3Params( --=20 2.41.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org