From nobody Fri Dec 12 12:53:26 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=1765293853; cv=none; d=zohomail.com; s=zohoarc; b=UI9VdTKxE0Ghi0kcN1Xr2ncT96+5KLYnRM1LQmwbdrPaZyj6uXO4nhq10Bche6YHL3R0G/yRYxNm9gM6815QI6xS4k0O8uc0bjnvQ7ukY6iQ0blWxAnrYH8CyqCgxfvgDRMYlhBsq97biGsGE3WEFziuV3hdcT67InaThT9PaSU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765293853; h=Content-Type:Content-Transfer-Encoding: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:Cc; bh=ANMVn1JdFpu1xtKoMUVfrtHgMJVheOWXvaMQ6Xcrsoo=; b=mL5SWg5JTwjqo6KqiN5fpOUPy2pC1/3Lbp5Cr+Ak7oP8FUwfn/8Gpx7xwMfZaeyfYZRjvFEBQMKEMrA84GqAjMn+QCK7BwA48YiOC3MRi2jDK7fTd3P1kk74rZ4Hn6sy+9TFRlZ7X/fI+8lZsKoO1J0gzTNS16n/8U8TmkdMbyA= 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 1765293853506840.1073344437681; Tue, 9 Dec 2025 07:24:13 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id AA17841941; Tue, 9 Dec 2025 10:24:12 -0500 (EST) Received: from [172.19.199.80] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 8A30B41AD2; Tue, 9 Dec 2025 10:23:21 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 02B1E4189F; Tue, 9 Dec 2025 10:03:51 -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 EA7CC41998 for ; Tue, 9 Dec 2025 10:03:50 -0500 (EST) Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-331-Von1RSgVPp6PCET5b93HbQ-1; Tue, 09 Dec 2025 10:03:35 -0500 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E71CD19560A1 for ; Tue, 9 Dec 2025 15:03:34 +0000 (UTC) Received: from orkuz (unknown [10.44.33.57]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4C36A30001A5 for ; Tue, 9 Dec 2025 15:03:34 +0000 (UTC) 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=1765292630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ANMVn1JdFpu1xtKoMUVfrtHgMJVheOWXvaMQ6Xcrsoo=; b=UzUMwEHagME4e7H9tFskGrL7FzWGN/aSIH5HXeO8UFWxAtx/l/RDwCuyfpREsXJSvQeo+7 G/LG4yR0jz0Q6L7D6nNKg633i9xS3/uFPb8AfL6oFvBdY0bxRdNJ6TJfsMshebaIwuuvPC JQiVBHoq5n0XfGYo0m5k5Js/HzUiDfo= X-MC-Unique: Von1RSgVPp6PCET5b93HbQ-1 X-Mimecast-MFC-AGG-ID: Von1RSgVPp6PCET5b93HbQ_1765292615 To: devel@lists.libvirt.org Subject: [PATCH 1/4] tests: Test virFileIsSharedFSOverride Date: Tue, 9 Dec 2025 16:02:27 +0100 Message-ID: <2e25a6621e93a6568fd131b11b0a062419297d3a.1765292471.git.jdenemar@redhat.com> In-Reply-To: References: 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: h_TSOMckF0VWSIe-YO3Y_-GtcODS1tUc6oWarCrmgJk_1765292615 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: MJQ6RZ3TMSXCA22W4X423QB2UOL23OJF X-Message-ID-Hash: MJQ6RZ3TMSXCA22W4X423QB2UOL23OJF X-MailFrom: jdenemar@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 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: Jiri Denemark via Devel Reply-To: Jiri Denemark X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1765293854942158500 Content-Type: text/plain; charset="utf-8" From: Jiri Denemark Technically virFileIsSharedFSOverride is available on any OS, but we need a mocked realpath() to test it. Because the virfilemock library also mocks statfs() which is only available on Linux, we don't even try to load the library anywhere else. Thus we need to skip testing virFileIsSharedFSOverride on non-Linux too. Signed-off-by: Jiri Denemark Reviewed-by: Michal Privoznik --- tests/virfiletest.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/virfiletest.c b/tests/virfiletest.c index e05925a321..ccd76a3fac 100644 --- a/tests/virfiletest.c +++ b/tests/virfiletest.c @@ -329,6 +329,55 @@ testFileIsSharedFSType(const void *opaque G_GNUC_UNUSE= D) } =20 =20 +static const char *shared_filesystems[] =3D { + "/run/user/501/gvfs", + "/nfs", + "/gluster", + "/ceph/multi", + "/gpfs/data/blaf", + "/quobyte", + NULL, +}; + +static int +testFileIsSharedFSOverride(const void *opaque G_GNUC_UNUSED) +{ +#ifndef __linux__ + return EXIT_AM_SKIP; +#else + const struct testFileIsSharedFSType *data =3D opaque; + g_autofree char *mtabFile =3D NULL; + bool actual; + int ret =3D -1; + + /* mtab is used by mocked realpath to decide whether a given path exis= ts */ + mtabFile =3D g_strdup_printf(abs_srcdir "/virfiledata/%s", data->mtabF= ile); + + if (!g_setenv("LIBVIRT_MTAB", mtabFile, true)) { + fprintf(stderr, "Unable to set env variable\n"); + goto cleanup; + } + + actual =3D virFileIsSharedFSOverride(data->filename, + (char * const *) shared_filesystems= ); + + if (actual !=3D data->expected) { + fprintf(stderr, "FS of '%s' is %s. Expected: %s\n", + data->filename, + actual ? "shared" : "not shared", + data->expected ? "shared" : "not shared"); + goto cleanup; + } + + ret =3D 0; + + cleanup: + g_unsetenv("LIBVIRT_MTAB"); + return ret; +#endif +} + + static int mymain(void) { @@ -439,6 +488,26 @@ mymain(void) DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gpfs/data", true); DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/quobyte", true); =20 +#define DO_TEST_FILE_IS_SHARED_FS_OVERRIDE(mtab, file, exp) \ + do { \ + struct testFileIsSharedFSType data =3D { \ + .mtabFile =3D mtab, .filename =3D file, .expected =3D exp \ + }; \ + if (virTestRun(virTestCounterNext(), testFileIsSharedFSOverride, &= data) < 0) \ + ret =3D -1; \ + } while (0) + + virTestCounterReset("testFileIsSharedFSOverride "); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/boot/vmlinuz", fal= se); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/run/user/501/gvfs/= some/file", true); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/nfs/file", true); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gluster/file", tru= e); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/some/symlink/file"= , true); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/file", false); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/multi/file", = true); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gpfs/data", false); + DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/quobyte", true); + return ret !=3D 0 ? EXIT_FAILURE : EXIT_SUCCESS; } =20 --=20 2.52.0 From nobody Fri Dec 12 12:53:26 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=1765293212; cv=none; d=zohomail.com; s=zohoarc; b=dlt5RZeCOPR5+/0ddUns/zUrpaqk8yLjrg6Vi4x7GE77I0Doh0tfZ20yCMMWe2MPyNXDWMcQzwnZPNv5ybZE1YuqMD5/1SV6iaQ9REG8gchharfIIoipN5nWCiy0grn/TKATkYZxcVdSS5kM9VsCmFgrZOKMDxHKsllePgaHD3c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765293212; h=Content-Type:Content-Transfer-Encoding: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:Cc; bh=TR0NWFrHYp0zb8lh7Ecm8Yn0zE7yFEzk3VGvSvjvQ0c=; b=aD51mDYEP74dOPM9TlZJlnjMdONxviauKJ1cDNktOC/9URiERdGYJ0dIDTmgwpn6KStr/XQNy7w8Yp6MIXKnZw2pt145K7TldOV8DdFAoWgUZ0l9AUjCLtkS64L+bqTo1jnjq9vzPSzNYOjBHXAE/y/c37RuX9te2D+NBox0Ihg= 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 1765293204053240.34778253442323; Tue, 9 Dec 2025 07:13:24 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 9D789418BE; Tue, 9 Dec 2025 10:13:21 -0500 (EST) Received: from [172.19.199.80] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id A402D41BF1; Tue, 9 Dec 2025 10:12:09 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id B42D64189F; Tue, 9 Dec 2025 10:03:41 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.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 19FBD41998 for ; Tue, 9 Dec 2025 10:03:40 -0500 (EST) 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-578-PVcatIN_PzynnHPtea99sQ-1; Tue, 09 Dec 2025 10:03:38 -0500 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4833A1800342 for ; Tue, 9 Dec 2025 15:03:37 +0000 (UTC) Received: from orkuz (unknown [10.44.33.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C2F81180045B for ; Tue, 9 Dec 2025 15:03:36 +0000 (UTC) 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=1765292619; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TR0NWFrHYp0zb8lh7Ecm8Yn0zE7yFEzk3VGvSvjvQ0c=; b=giux9YkI31cnLyKsQl9/aaLvfmw7f/YFJQA3Fo3vbhS/qfk5apRnyuReDE8Iff7TJZgbNR LuQ/i249Jua9JKrjq6BwnFc0/sfmoGvd/7xSzvShy7l2vygSu51ow2qg2gMNV6R8scMMJ0 F7ALfxadma6Qh5dpJCrIHKLf5p9n4H8= X-MC-Unique: PVcatIN_PzynnHPtea99sQ-1 X-Mimecast-MFC-AGG-ID: PVcatIN_PzynnHPtea99sQ_1765292617 To: devel@lists.libvirt.org Subject: [PATCH 2/4] util: Fix race condition in virFileIsSharedFSType Date: Tue, 9 Dec 2025 16:02:28 +0100 Message-ID: <5fee3f2b6337f31911390c0a94278e77b99bdbfb.1765292471.git.jdenemar@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: nz4bu7uNhOCQxtEKEZ6cqnRv4IOME8iYeX4_95-DKI8_1765292617 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: ZZIVZXUSGNBCHXFLKFFSDXJSYP6H4VN4 X-Message-ID-Hash: ZZIVZXUSGNBCHXFLKFFSDXJSYP6H4VN4 X-MailFrom: jdenemar@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 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: Jiri Denemark via Devel Reply-To: Jiri Denemark X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1765293217201158500 Content-Type: text/plain; charset="utf-8" From: Jiri Denemark virFileIsSharedFSType could end up calling statfs on a path that no longer exists and return an error. If this happens for a path on a shared filesystem, the caller may incorrectly consider the path as non-shared. Specifically, when starting a domain with TPM enabled and deciding whether its vTPM state is stored on a shared storage, the race could cause qemuTPMEmulatorBuildCommand to consider the state to be non-shared. This means swtpm would be started without --migration even when the state is actually stored on a shared storage and any attempt to migrate such domain would fail with Operation not supported: the running swtpm does not support migration with shared storage In fact, any caller of virFileGetExistingParent contained an inherent TOCTOU race condition as the existing parent of a given path return by virFileGetExistingParent may no longer exist at the time the caller wants to check it. This patch introduces a new virFileCheckParents API which is almost identical to virFileGetExistingParent, but uses a supplied callback to check each path. This new API is used in virFileIsSharedFSType to avoid the race. The old function will later be completely removed once all callers are switched to the new one. Fixes: 05526b50909ff50c16e13a0b5580d41de74e3d59 Signed-off-by: Jiri Denemark Reviewed-by: Michal Privoznik --- src/util/virfile.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index f195d02e29..b0f4041df4 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -3445,6 +3445,63 @@ virFileRemoveLastComponent(char *path) } =20 =20 +/* Check callback for virFileCheckParents */ +typedef bool (*virFileCheckParentsCallback)(const char *dirpath, + void *opaque); + +/** + * virFileCheckParents: + * @path: path to check + * @parent: where to store the closest parent satisfying the check + * @check: callback called on parent paths + * @opaque: data for the @check callback + * + * Calls @check on the @path and its parent paths until it returns true or= a + * root directory is reached. When @check returns true, the @parent (if + * non-NULL) will be set to a copy of the corresponding path. The caller is + * responsible for freeing it. + * + * Returns 0 on success (@parent set), + * -1 on invalid input, + * -2 when no path (including "/") satisfies the @check. + */ +static int +virFileCheckParents(const char *path, + char **parent, + virFileCheckParentsCallback check, + void *opaque) +{ + g_autofree char *dirpath =3D g_strdup(path); + char *p =3D NULL; + bool checkOK; + + checkOK =3D check(dirpath, opaque); + + while (!checkOK && p !=3D dirpath) { + if (!(p =3D strrchr(dirpath, G_DIR_SEPARATOR))) { + virReportSystemError(EINVAL, + _("Invalid absolute path '%1$s'"), path); + return -1; + } + + if (p =3D=3D dirpath) + *(p + 1) =3D '\0'; + else + *p =3D '\0'; + + checkOK =3D check(dirpath, opaque); + } + + if (!checkOK) + return -2; + + if (parent) + *parent =3D g_steal_pointer(&dirpath); + + return 0; +} + + static char * virFileGetExistingParent(const char *path) { @@ -3599,6 +3656,14 @@ static const struct virFileSharedFsData virFileShare= dFs[] =3D { }; =20 =20 +static bool +virFileCheckParentsStatFS(const char *path, + void *opaque) +{ + return statfs(path, (struct statfs *) opaque) =3D=3D 0; +} + + int virFileIsSharedFSType(const char *path, unsigned int fstypes) @@ -3607,11 +3672,13 @@ virFileIsSharedFSType(const char *path, struct statfs sb; long long f_type =3D 0; size_t i; + int rc; =20 - if (!(dirpath =3D virFileGetExistingParent(path))) + if ((rc =3D virFileCheckParents(path, &dirpath, + virFileCheckParentsStatFS, &sb)) =3D=3D = -1) return -1; =20 - if (statfs(dirpath, &sb) < 0) { + if (rc !=3D 0) { virReportSystemError(errno, _("cannot determine filesystem for '%1$s'"), path); --=20 2.52.0 From nobody Fri Dec 12 12:53:26 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=1765293373; cv=none; d=zohomail.com; s=zohoarc; b=N79+qUTyYFBlI4hSI0zSxy5tMJ+s0bLJGe+KztEt8KrvEnEmqJLUNOhplFAoiQt1b7klCT1IfLBUIc83NMiKJohtsB9fEfKS1VYJZuKvbiB1Sbyc93rbMhfy+zj/hEthZ3th+5z7d+u9TTEfhegwh5lA6Ye7wZ3FCRtT0liBwFY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765293373; h=Content-Type:Content-Transfer-Encoding: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:Cc; bh=jsOkJVnfnN8CcwXzIsEbFXNhJLsUG631shyXKgDIWcs=; b=WqHQqZAldZwhhkpWohXsd8OPftvd85GEai6Qr2ZzBqZzg4J8u3PWY0oFyb5lgRa2pVlT+fqqHcFSEpr3HJBDe+qGNRktwYqZXiWPLkoE4r4Mr/ycPcYyLseMJDE3Mt/tJSz7PUMG/P05/hpZiDfSiZgDh9iRvB0AIfV1OwUPb4Y= 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 1765293373122188.93158930369668; Tue, 9 Dec 2025 07:16:13 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 3D000418BE; Tue, 9 Dec 2025 10:16:11 -0500 (EST) Received: from [172.19.199.80] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id C139F43DEA; Tue, 9 Dec 2025 10:15:02 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 5CB3D419A5; Tue, 9 Dec 2025 10:03:43 -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 50CED41998 for ; Tue, 9 Dec 2025 10:03:42 -0500 (EST) Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-597-X67Ndys6MyeWhK_whLNwoA-1; Tue, 09 Dec 2025 10:03:40 -0500 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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ECD131955F0E for ; Tue, 9 Dec 2025 15:03:39 +0000 (UTC) Received: from orkuz (unknown [10.44.33.57]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5E04030001A5 for ; Tue, 9 Dec 2025 15:03:39 +0000 (UTC) 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=1765292622; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jsOkJVnfnN8CcwXzIsEbFXNhJLsUG631shyXKgDIWcs=; b=E7zmTWRUFIAl8kVvP7SBcFmRrQZYLZgVCoq1XCQ5ckxvbdbnTP9mmgmWpu8Xi7XDcMQWMD YqfTp4rXOA1lNn2D98DtoNlydIWUGZ4gwK2nrx/FEBF4HCwe5kjGZDQDm/a0odq+3XMWwx 5wAYFdbIui5N49DW8DUUViwsjFubeig= X-MC-Unique: X67Ndys6MyeWhK_whLNwoA-1 X-Mimecast-MFC-AGG-ID: X67Ndys6MyeWhK_whLNwoA_1765292620 To: devel@lists.libvirt.org Subject: [PATCH 3/4] util: Fix race condition in virFileIsSharedFSOverride Date: Tue, 9 Dec 2025 16:02:29 +0100 Message-ID: In-Reply-To: References: 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: 44b8A4OPrx9hgHm0ICzt_9nAfxmDrIxlZWpyoK68qtI_1765292620 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: JUDWUBICRA6MYBUG32TDTL6MFGYP4HDD X-Message-ID-Hash: JUDWUBICRA6MYBUG32TDTL6MFGYP4HDD X-MailFrom: jdenemar@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 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: Jiri Denemark via Devel Reply-To: Jiri Denemark X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1765293374426158500 Content-Type: text/plain; charset="utf-8" From: Jiri Denemark Switch virFileIsSharedFSOverride to use virFileCheckParents to avoid a race which could result in virFileCanonicalizePath to be called on a path that does not exist anymore. Signed-off-by: Jiri Denemark Reviewed-by: Michal Privoznik --- src/util/virfile.c | 59 +++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index b0f4041df4..ea68215655 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -3502,33 +3502,6 @@ virFileCheckParents(const char *path, } =20 =20 -static char * -virFileGetExistingParent(const char *path) -{ - g_autofree char *dirpath =3D g_strdup(path); - char *p =3D NULL; - - /* Try less and less of the path until we get to a directory we can ac= cess. - * Even if we don't have 'x' permission on any directory in the path o= n the - * NFS server (assuming it's NFS), we will be able to stat the mount p= oint. - */ - while (!virFileExists(dirpath) && p !=3D dirpath) { - if (!(p =3D strrchr(dirpath, '/'))) { - virReportSystemError(EINVAL, - _("Invalid relative path '%1$s'"), path); - return NULL; - } - - if (p =3D=3D dirpath) - *(p + 1) =3D '\0'; - else - *p =3D '\0'; - } - - return g_steal_pointer(&dirpath); -} - - #ifdef __linux__ =20 # ifndef NFS_SUPER_MAGIC @@ -3875,6 +3848,17 @@ virFileGetDefaultHugepage(virHugeTLBFS *fs, } =20 =20 +static bool +virFileCheckParentsCanonicalize(const char *path, + void *opaque) +{ + char **canonical =3D opaque; + + *canonical =3D virFileCanonicalizePath(path); + return !!*canonical; +} + + /** * virFileIsSharedFSOverride: * @path: Path to check @@ -3888,24 +3872,25 @@ virFileIsSharedFSOverride(const char *path, char *const *overrides) { g_autofree char *dirpath =3D NULL; - g_autofree char *existing =3D NULL; char *p =3D NULL; + int rc; =20 if (!path || path[0] !=3D '/' || !overrides) return false; =20 /* We only care about the longest existing sub-path. Further components - * may will later be created by libvirt will not magically become a sh= ared - * filesystem. */ - if (!(existing =3D virFileGetExistingParent(path))) + * that may later be created by libvirt will not magically become a sh= ared + * filesystem. Overrides have been canonicalized ahead of time, so we = need + * to do the same for the provided path or we'll never be able to find= a + * match if symlinks are involved. + */ + rc =3D virFileCheckParents(path, NULL, + virFileCheckParentsCanonicalize, &dirpath); + if (rc =3D=3D -1) return false; =20 - /* Overrides have been canonicalized ahead of time, so we need to - * do the same for the provided path or we'll never be able to - * find a match if symlinks are involved */ - if (!(dirpath =3D virFileCanonicalizePath(existing))) { - VIR_DEBUG("Cannot canonicalize parent '%s' of path '%s'", - existing, path); + if (rc !=3D 0) { + VIR_DEBUG("Cannot canonicalize path '%s'", path); return false; } =20 --=20 2.52.0 From nobody Fri Dec 12 12:53:26 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=1765293698; cv=none; d=zohomail.com; s=zohoarc; b=a84OVIyDiCO3mRvG0vK8ba65pPqavL754e42gBHJ5oP2urvNFmMTQYjGEmPS9BPIzXuWOGTyTePi4lBIFDhM+By3JKhEeqatbccOgw/IPzyhB1WwGrJzmdksGq0leoPnx2PD9VgDiMZjyRe2YZw/ijz4gLNambmMZTzf9pjydRA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1765293698; h=Content-Type:Content-Transfer-Encoding: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:Cc; bh=vBmjSl01G8VOcA+kloK1d0XxCbBtULbRoZQQJLHpzWw=; b=hyLa8m76tnpi2q1K6bx2YVBx2ZIkt9fvsW6+hPRP3cMzxur1lnBdEs1LSZ2LEq50yTASqJ+2GJ4jGQ9H5JUk4dsTOjdOQQWydpMv49co5gGYWHmTgO8HyofAYpaj3/abSKnGyyMeP0cIbRdQPI+iWMlhMZ0r7YyOogehDPVbH4c= 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 1765293698262709.6207560160539; Tue, 9 Dec 2025 07:21:38 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 73E27418E7; Tue, 9 Dec 2025 10:21:35 -0500 (EST) Received: from [172.19.199.80] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id E5AF041BBC; Tue, 9 Dec 2025 10:20:27 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id C68BD41998; Tue, 9 Dec 2025 10:03:45 -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 EFA564189F for ; Tue, 9 Dec 2025 10:03:44 -0500 (EST) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-297-NDfLcFQJP0qe95bHZ1QxYA-1; Tue, 09 Dec 2025 10:03:43 -0500 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 378EF19560A5 for ; Tue, 9 Dec 2025 15:03:42 +0000 (UTC) Received: from orkuz (unknown [10.44.33.57]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8D2931956095 for ; Tue, 9 Dec 2025 15:03:41 +0000 (UTC) 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=1765292624; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vBmjSl01G8VOcA+kloK1d0XxCbBtULbRoZQQJLHpzWw=; b=JOrSugT1wCttrVxJ24mh5oaKTRHJqn2VsBUgGtyNANxFwh/1zLxsxGEWE1saMWXVIsq7+c Q+JO+wUtpZ6S+nhlPr4Q8uK07Hpynh7TsnYqQ0rEaaVm4bhtiZiV0RUgT7AGpujMoiGCXO 5Yy1MPYgs3YaHC1Rx+dznkDggRDacsQ= X-MC-Unique: NDfLcFQJP0qe95bHZ1QxYA-1 X-Mimecast-MFC-AGG-ID: NDfLcFQJP0qe95bHZ1QxYA_1765292622 To: devel@lists.libvirt.org Subject: [PATCH 4/4] util: Rework virFileIsSharedFSOverride using virFileCheckParents Date: Tue, 9 Dec 2025 16:02:30 +0100 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ijaUW4gvkjslAlPc5xFh6tgZ3nvPU5iyHbMNH6tUeRQ_1765292622 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: TPXTKIESQIQOTG2YBHKAEPZQ6RSWH762 X-Message-ID-Hash: TPXTKIESQIQOTG2YBHKAEPZQ6RSWH762 X-MailFrom: jdenemar@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 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: Jiri Denemark via Devel Reply-To: Jiri Denemark X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1765293699889158500 Content-Type: text/plain; charset="utf-8" From: Jiri Denemark The newly introduced virFileCheckParents is generic enough to be used for checking whether a specific path or any of its parents is included in the overrides array. Signed-off-by: Jiri Denemark Reviewed-by: Michal Privoznik --- src/util/virfile.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index ea68215655..9316606ce8 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -3859,6 +3859,14 @@ virFileCheckParentsCanonicalize(const char *path, } =20 =20 +static bool +virFileCheckParentsInOverrides(const char *path, + void *opaque) +{ + return g_strv_contains((const char *const *) opaque, path); +} + + /** * virFileIsSharedFSOverride: * @path: Path to check @@ -3872,7 +3880,6 @@ virFileIsSharedFSOverride(const char *path, char *const *overrides) { g_autofree char *dirpath =3D NULL; - char *p =3D NULL; int rc; =20 if (!path || path[0] !=3D '/' || !overrides) @@ -3894,29 +3901,11 @@ virFileIsSharedFSOverride(const char *path, return false; } =20 - if (g_strv_contains((const char *const *) overrides, dirpath)) - return true; + if (virFileCheckParents(dirpath, NULL, virFileCheckParentsInOverrides, + (void *) overrides) < 0) + return false; =20 - /* Continue until we've scanned the entire path */ - while (p !=3D dirpath) { - - /* Find the last slash */ - if ((p =3D strrchr(dirpath, '/')) =3D=3D NULL) - break; - - /* Truncate the path by overwriting the slash that we've just - * found with a null byte. If it is the very first slash in - * the path, we need to handle things slightly differently */ - if (p =3D=3D dirpath) - *(p+1) =3D '\0'; - else - *p =3D '\0'; - - if (g_strv_contains((const char *const *) overrides, dirpath)) - return true; - } - - return false; + return true; } =20 =20 --=20 2.52.0