]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
security: Ensure file exists before attempting to restore label
authorJim Fehlig <jfehlig@suse.com>
Mon, 25 Mar 2024 22:38:19 +0000 (16:38 -0600)
committerJim Fehlig <jfehlig@suse.com>
Mon, 8 Apr 2024 16:38:25 +0000 (10:38 -0600)
When performing an install, it's common for tooling such as virt-install
to remove the install kernel/initrd once they are successfully booted and
the domain has been redefined to boot without them. After the installation
is complete and the domain is rebooted/shutdown, the DAC and selinux
security drivers attempt to restore labels on the now deleted files. It's
harmles wrt functionality, but results in error messages such as

Mar 08 12:40:37 virtqemud[5639]: internal error: child reported (status=125): unable to stat: /var/lib/libvirt/boot/vir>
Mar 08 12:40:37 virtqemud[5639]: unable to stat: /var/lib/libvirt/boot/virtinst-yvp19moo-linux: No such file or directo>
Mar 08 12:40:37 virtqemud[5639]: Unable to run security manager transaction

Add a check for file existence to the virSecurity*RestoreFileLabel functions,
and avoid relabeling if the file is no longer available. Skipping the restore
caused failures in qemusecuritytest, which mocks stat, chown, etc as part of
ensuring the security drivers properly restore labels. virFileExists is now
mocked in qemusecuritymock.c to return true when passed a file previously
seen by the mocked stat, chown, etc functions.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/security/security_dac.c
src/security/security_selinux.c
tests/qemusecuritymock.c

index 567be4bd230667592790684daf24d88f8dbbd931..4e850e219e33766dc0247af99422bb1088739863 100644 (file)
@@ -825,6 +825,9 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManager *mgr,
         virStorageSourceIsLocalStorage(src))
         path = src->path;
 
+    if (!virFileExists(path))
+        return 0;
+
     /* Be aware that this function might run in a separate process.
      * Therefore, any driver state changes would be thrown away. */
 
index b49af26e4935d9d6bfe3e1d03fc5555abcb2ff55..aaec34ff8bd942cae6965bdabfd04d4af3087fa9 100644 (file)
@@ -1488,6 +1488,8 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManager *mgr,
      */
     if (!path)
         return 0;
+    if (!virFileExists(path))
+        return 0;
 
     VIR_INFO("Restoring SELinux context on '%s'", path);
 
index 80d59536b10de6d21a7bedf037c7b910a3c20a12..a7bb1f8bea9c392674a911b8e95a7333ea3dcac4 100644 (file)
@@ -66,6 +66,7 @@ static int (*real_close)(int fd);
 static int (*real_setfilecon_raw)(const char *path, const char *context);
 static int (*real_getfilecon_raw)(const char *path, char **context);
 #endif
+static bool (*real_virFileExists)(const char *file);
 
 
 /* Global mutex to avoid races */
@@ -123,6 +124,7 @@ init_syms(void)
     VIR_MOCK_REAL_INIT(setfilecon_raw);
     VIR_MOCK_REAL_INIT(getfilecon_raw);
 #endif
+    VIR_MOCK_REAL_INIT(virFileExists);
 
     /* Intentionally not calling init_hash() here */
 }
@@ -382,6 +384,24 @@ int virFileUnlock(int fd G_GNUC_UNUSED,
 }
 
 
+bool virFileExists(const char *path)
+{
+    VIR_LOCK_GUARD lock = virLockGuardLock(&m);
+
+    if (getenv(ENVVAR) == NULL)
+        return real_virFileExists(path);
+
+    init_hash();
+    if (virHashHasEntry(chown_paths, path))
+        return true;
+
+    if (virHashHasEntry(selinux_paths, path))
+        return true;
+
+    return false;
+}
+
+
 typedef struct _checkOwnerData checkOwnerData;
 struct _checkOwnerData {
     GHashTable *paths;