]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
selinux: Don't ignore ENOENT in Permissive mode
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 20 Sep 2021 11:02:37 +0000 (13:02 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 20 Feb 2023 10:04:21 +0000 (11:04 +0100)
In selinux driver there's virSecuritySELinuxSetFileconImpl()
which is responsible for actual setting of SELinux label on given
file and handling possible failures. In fhe failure handling code
we decide whether failure is fatal or not. But there is a bug:
depending on SELinux mode (Permissive vs. Enforcing) the ENOENT
is either ignored or considered fatal. This not correct - ENOENT
must always be fatal for couple of reasons:

- In virSecurityStackTransactionCommit() the seclabels are set
  for individual secdrivers (e.g. SELinux first and then DAC),
  but if one secdriver succeeds and another one fails, then no
  rollback is performed for the successful one leaking remembered
  labels.

- QEMU would fail opening the file anyways (if neither of
  secdrivers reported error and thus cancelled domain startup)

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2004850
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
src/security/security_selinux.c

index e9c4051a9823b3f5a410a5af04d58788df7c9e91..e43962435f23a05864b9d1766b660f4e87028b30 100644 (file)
@@ -1280,9 +1280,11 @@ virSecuritySELinuxSetFileconImpl(const char *path,
         } else {
             /* However, don't claim error if SELinux is in Enforcing mode and
              * we are running as unprivileged user and we really did see EPERM.
-             * Otherwise we want to return error if SELinux is Enforcing. */
-            if (security_getenforce() == 1 &&
-                (setfilecon_errno != EPERM || privileged)) {
+             * Otherwise we want to return error if SELinux is Enforcing, or we
+             * saw ENOENT regardless of SELinux mode. */
+            if (setfilecon_errno == ENOENT ||
+                (security_getenforce() == 1 &&
+                 (setfilecon_errno != EPERM || privileged))) {
                 virReportSystemError(setfilecon_errno,
                                      _("unable to set security context '%s' on '%s'"),
                                      tcon, path);