From nobody Sun Dec 14 01:57:44 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=1750695459; cv=none; d=zohomail.com; s=zohoarc; b=ARxmacqlU11MKAe1HnxgnW1gUB9bWItZE4HiM/LRri0atmdrjrRBmETU7wdMm4zvzGG/wRGS5Wy09YHLokhqGDAKYpXn0eoRFsEnSRAp/TPlx3rer3P7VEkqrpnBfWZoMHA22yUGtiv8CGYGnIoLtEzDdoOh/rK17uyDRPYHD9w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750695459; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:Subject:Subject:To:To:Message-Id; bh=rokmW1sX5rf6jk9/wvutp4AQMT99TEIDThZ2XBzKB0c=; b=BinQbzj0/62x3sKg7IuDFk41L/4yf3g8kNQ9jrMJrXqogF45yzmAkDGVLbOzw+IXJ1mhBnpkx+rxECt++36poiLjBwFpbBRgxC3pTVMdZpWEkZCfyOYUIyiH9kf55Ba9icjTXuci8gZxBVXvTf/nFYELo+BJN5/DA1OrVM8d6gs= 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 175069545965226.004655011007344; Mon, 23 Jun 2025 09:17:39 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 94195ABA; Mon, 23 Jun 2025 12:17:38 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id CD37D9E9; Mon, 23 Jun 2025 12:17:14 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 0617EA0B; Mon, 23 Jun 2025 12:17:12 -0400 (EDT) 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 7F71CA0D for ; Mon, 23 Jun 2025 12:17:11 -0400 (EDT) Received: from mx-prod-mc-08.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-79-DiUXjrEhPMidJqEq_Kfigw-1; Mon, 23 Jun 2025 12:17:10 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3CA5B1809C82 for ; Mon, 23 Jun 2025 16:17:09 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.95]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 29BE330001A1; Mon, 23 Jun 2025 16:17:07 +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.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750695431; 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; bh=6ldf7IaIfQ1cnoM7K3nsQCMujifBh1fJJqbnmEAZDlk=; b=MssPdu3ZV/P/xOKvYb9HK6viqe+DS8TNkli4UuKbi0bR7xmOb2Wumzjc/qQ362HtX/EPOq s9LY0ncDHf5OYY6H+5HsyihVUgDEAYFlwIMVu5l1iM2NsUDmvkPcbvXdejq17koFClFDCT SHlHvWYZgnsUwsHmA8KMLYh03o8Acuo= X-MC-Unique: DiUXjrEhPMidJqEq_Kfigw-1 X-Mimecast-MFC-AGG-ID: DiUXjrEhPMidJqEq_Kfigw_1750695429 To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2] util: workaround libxml2 lack of thread safe initialization Date: Mon, 23 Jun 2025 17:17:06 +0100 Message-ID: <20250623161706.3800363-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 6dbTz2D6m1uoZlmf1WclyJmXYT9f_UhE7wgqv8gKsr4_1750695429 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: COOPH57DUEEHA3D6755GZSATKP2APY5S X-Message-ID-Hash: COOPH57DUEEHA3D6755GZSATKP2APY5S 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: From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9_via_Devel?= Reply-To: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1750695467279116600 Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The main XML parser code global initializer historically had a mutex protecting it, and more recently uses a pthread_once. The RelaxNG code, however, relies on two other global initializers that are not thread safe, just relying on setting an integer "initialized" flag. Calling the relevant initializers from libvirt in a protected global initializer will protect libvirt's own concurrent usage, however, it cannot protect against other libraries loaded in process that might be using libxml2's schema code. Fortunately: * The chances of other loaded non-libvirt code using libxml is relatively low * The chances of other loaded non-libvirt code using the schema validation / catalog functionality inside libxml is even lower * The chances of both libvirt and the non-libvirt usage having their *1st* usage of libxml2 be concurrent is tiny IOW, in practice, although our solution doesn't fully fix the thread safety, it is good enough. libxml2 should none the less still be fixed to make its global initializers be thread safe without special actions by its API consumers[1]. Resolves: https://gitlab.com/libvirt/libvirt/-/issues/788 [1] https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/326 Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- Changed in v3: - Drop xmlInitializeCatalog - I misread the code wrt thread safety - it has a sufficiently protective mutex - Cope with return type change for xmlSchemaInitTypes in libxml >=3D 2.11.0 src/util/virxml.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/util/virxml.c b/src/util/virxml.c index 9d46e5f32f..c851d6f407 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -26,6 +26,8 @@ =20 #include #include +#include +#include =20 #include "virerror.h" #include "virxml.h" @@ -35,6 +37,7 @@ #include "virstring.h" #include "virutil.h" #include "viruuid.h" +#include "virthread.h" #include "configmake.h" =20 #define VIR_FROM_THIS VIR_FROM_XML @@ -50,6 +53,28 @@ struct virParserData { }; =20 =20 +static int +virXMLSchemaOnceInit(void) +{ +#if LIBXML_VERSION >=3D 21100 + if (xmlSchemaInitTypes() < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to initialize libxml2 schema types")); + return -1; + } +#else + xmlSchemaInitTypes(); +#endif + if (xmlRelaxNGInitTypes() < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to initialize libxml2 RelaxNG data")); + return -1; + } + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virXMLSchema); + static xmlXPathContextPtr virXMLXPathContextNew(xmlDocPtr xml) { @@ -1603,6 +1628,9 @@ virXMLValidatorInit(const char *schemafile) { g_autoptr(virXMLValidator) validator =3D NULL; =20 + if (virXMLSchemaInitialize() < 0) + return NULL; + validator =3D g_new0(virXMLValidator, 1); =20 validator->schemafile =3D g_strdup(schemafile); --=20 2.49.0