From fbd36ae01b3459dd28e21eab95642371e0e91d4c Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 20 Sep 2021 13:02:37 +0200 Subject: [PATCH] selinux: Don't ignore ENOENT in Permissive mode 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 Reviewed-by: Martin Kletzander --- src/security/security_selinux.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index e9c4051a98..e43962435f 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -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);