From nobody Sun Feb 8 22:57:53 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1542962651336928.805099121628; Fri, 23 Nov 2018 00:44:11 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1D65589AEF; Fri, 23 Nov 2018 08:44:06 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D216E1057065; Fri, 23 Nov 2018 08:44:05 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 858343F606; Fri, 23 Nov 2018 08:44:05 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wAN8hqrP003872 for ; Fri, 23 Nov 2018 03:43:52 -0500 Received: by smtp.corp.redhat.com (Postfix) id C512317B26; Fri, 23 Nov 2018 08:43:52 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 244DF194AE for ; Fri, 23 Nov 2018 08:43:51 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Fri, 23 Nov 2018 09:43:30 +0100 Message-Id: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 12/18] security_selinux: Remember old labels X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 23 Nov 2018 08:44:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Michal Privoznik --- src/security/security_selinux.c | 161 ++++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 47 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 715d9a428b..4990d94b5f 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -33,6 +33,7 @@ =20 #include "security_driver.h" #include "security_selinux.h" +#include "security_util.h" #include "virerror.h" #include "viralloc.h" #include "virlog.h" @@ -197,14 +198,40 @@ virSecuritySELinuxTransactionAppend(const char *path, } =20 =20 +static int +virSecuritySELinuxRememberLabel(const char *path, + const security_context_t con) +{ + return virSecuritySetRememberedLabel(SECURITY_SELINUX_NAME, + path, con); +} + + +static int +virSecuritySELinuxRecallLabel(const char *path, + security_context_t *con) +{ + if (virSecurityGetRememberedLabel(SECURITY_SELINUX_NAME, + path, con) < 0) + return -1; + + if (!con) + return 1; + + return 0; +} + + static int virSecuritySELinuxSetFileconHelper(const char *path, const char *tcon, bool optional, - bool privileged); + bool privileged, + bool remember); =20 =20 static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, - const char *path); + const char *path, + bool recall); =20 =20 /** @@ -255,10 +282,12 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_= UNUSED, rv =3D virSecuritySELinuxSetFileconHelper(item->path, item->tcon, item->optional, - privileged); + privileged, + list->lock); } else { rv =3D virSecuritySELinuxRestoreFileLabel(list->manager, - item->path); + item->path, + list->lock); } =20 if (rv < 0) @@ -1275,16 +1304,38 @@ virSecuritySELinuxSetFileconImpl(const char *path, = const char *tcon, =20 static int virSecuritySELinuxSetFileconHelper(const char *path, const char *tcon, - bool optional, bool privileged) + bool optional, bool privileged, bool re= member) { + security_context_t econ =3D NULL; int rc; + int ret =3D -1; =20 if ((rc =3D virSecuritySELinuxTransactionAppend(path, tcon, optional, = false)) < 0) return -1; else if (rc > 0) return 0; =20 - return virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileg= ed); + if (remember) { + if (getfilecon_raw(path, &econ) < 0 && + errno !=3D ENOTSUP && errno !=3D ENODATA) { + virReportSystemError(errno, + _("unable to get SELinux context of %s"), + path); + goto cleanup; + } + + if (econ && + virSecuritySELinuxRememberLabel(path, econ) < 0) + goto cleanup; + } + + if (virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileged)= < 0) + goto cleanup; + + ret =3D 0; + cleanup: + freecon(econ); + return ret; } =20 =20 @@ -1293,7 +1344,7 @@ virSecuritySELinuxSetFileconOptional(virSecurityManag= erPtr mgr, const char *path, const char *tcon) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged= ); + return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged= , false); } =20 static int @@ -1301,7 +1352,7 @@ virSecuritySELinuxSetFilecon(virSecurityManagerPtr mg= r, const char *path, const char *tcon) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, false, privilege= d); + return virSecuritySELinuxSetFileconHelper(path, tcon, false, privilege= d, false); } =20 static int @@ -1362,7 +1413,8 @@ getContext(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, * errors that the caller(s) are already dealing with */ static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, - const char *path) + const char *path, + bool recall) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); struct stat buf; @@ -1386,26 +1438,35 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManag= erPtr mgr, goto cleanup; } =20 - if (stat(newpath, &buf) !=3D 0) { - VIR_WARN("cannot stat %s: %s", newpath, - virStrerror(errno, ebuf, sizeof(ebuf))); - goto cleanup; - } - - if (getContext(mgr, newpath, buf.st_mode, &fcon) < 0) { - /* Any user created path likely does not have a default label, - * which makes this an expected non error - */ - VIR_WARN("cannot lookup default selinux label for %s", newpath); - ret =3D 0; - goto cleanup; - } - - if ((rc =3D virSecuritySELinuxTransactionAppend(path, fcon, false, tru= e)) < 0) + if ((rc =3D virSecuritySELinuxTransactionAppend(path, NULL, false, tru= e)) < 0) return -1; else if (rc > 0) return 0; =20 + if (recall) { + if ((rc =3D virSecuritySELinuxRecallLabel(newpath, &fcon)) < 0) { + goto cleanup; + } else if (rc > 0) { + ret =3D 0; + goto cleanup; + } + } else { + if (stat(newpath, &buf) !=3D 0) { + VIR_WARN("cannot stat %s: %s", newpath, + virStrerror(errno, ebuf, sizeof(ebuf))); + goto cleanup; + } + + if (getContext(mgr, newpath, buf.st_mode, &fcon) < 0) { + /* Any user created path likely does not have a default label, + * which makes this an expected non error + */ + VIR_WARN("cannot lookup default selinux label for %s", newpath= ); + ret =3D 0; + goto cleanup; + } + } + if (virSecuritySELinuxSetFileconImpl(newpath, fcon, false, privileged)= < 0) goto cleanup; =20 @@ -1460,7 +1521,7 @@ virSecuritySELinuxRestoreInputLabel(virSecurityManage= rPtr mgr, =20 switch ((virDomainInputType)input->type) { case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: - rc =3D virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev= ); + rc =3D virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev= , false); break; =20 case VIR_DOMAIN_INPUT_TYPE_MOUSE: @@ -1516,7 +1577,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManag= erPtr mgr, if (!seclabel || !seclabel->relabel) return 0; =20 - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath, f= alse); break; =20 case VIR_DOMAIN_MEMORY_MODEL_DIMM: @@ -1595,10 +1656,10 @@ virSecuritySELinuxRestoreTPMFileLabelInt(virSecurit= yManagerPtr mgr, switch (tpm->type) { case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: tpmdev =3D tpm->data.passthrough.source.data.file.path; - rc =3D virSecuritySELinuxRestoreFileLabel(mgr, tpmdev); + rc =3D virSecuritySELinuxRestoreFileLabel(mgr, tpmdev, false); =20 if ((cancel_path =3D virTPMCreateCancelPath(tpmdev)) !=3D NULL) { - if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path, false= ) < 0) rc =3D -1; VIR_FREE(cancel_path); } @@ -1665,7 +1726,7 @@ virSecuritySELinuxRestoreImageLabelInt(virSecurityMan= agerPtr mgr, } } =20 - return virSecuritySELinuxRestoreFileLabel(mgr, src->path); + return virSecuritySELinuxRestoreFileLabel(mgr, src->path, false); } =20 =20 @@ -2053,7 +2114,7 @@ virSecuritySELinuxRestorePCILabel(virPCIDevicePtr dev= ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 static int @@ -2063,7 +2124,7 @@ virSecuritySELinuxRestoreUSBLabel(virUSBDevicePtr dev= ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 =20 @@ -2080,7 +2141,7 @@ virSecuritySELinuxRestoreSCSILabel(virSCSIDevicePtr d= ev, if (virSCSIDeviceGetShareable(dev) || virSCSIDeviceGetReadonly(dev)) return 0; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 static int @@ -2090,7 +2151,7 @@ virSecuritySELinuxRestoreHostLabel(virSCSIVHostDevice= Ptr dev ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 =20 @@ -2194,7 +2255,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecuri= tyManagerPtr mgr, if (!(vfiodev =3D virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuids= tr))) goto done; =20 - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfiodev); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false); =20 VIR_FREE(vfiodev); break; @@ -2228,7 +2289,7 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurity= ManagerPtr mgr, if (VIR_STRDUP(path, dev->source.caps.u.storage.block) < 0) return -1; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false); VIR_FREE(path); break; } @@ -2242,7 +2303,7 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurity= ManagerPtr mgr, if (VIR_STRDUP(path, dev->source.caps.u.misc.chardev) < 0) return -1; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false); VIR_FREE(path); break; } @@ -2390,14 +2451,18 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityMa= nagerPtr mgr, switch (dev_source->type) { case VIR_DOMAIN_CHR_TYPE_DEV: case VIR_DOMAIN_CHR_TYPE_FILE: - if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.= path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.file.path, + false) < 0) goto done; ret =3D 0; break; =20 case VIR_DOMAIN_CHR_TYPE_UNIX: if (!dev_source->data.nix.listen) { - if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.f= ile.path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.file.p= ath, + false) < 0) goto done; } ret =3D 0; @@ -2408,11 +2473,13 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityMa= nagerPtr mgr, (virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0)) goto done; if (virFileExists(in) && virFileExists(out)) { - if ((virSecuritySELinuxRestoreFileLabel(mgr, out) < 0) || - (virSecuritySELinuxRestoreFileLabel(mgr, in) < 0)) { + if ((virSecuritySELinuxRestoreFileLabel(mgr, out, false) < 0) = || + (virSecuritySELinuxRestoreFileLabel(mgr, in, false) < 0)) { goto done; } - } else if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->dat= a.file.path) < 0) { + } else if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.fil= e.path, + false) < 0) { goto done; } ret =3D 0; @@ -2464,7 +2531,7 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(vi= rDomainDefPtr def, database =3D dev->data.cert.database; if (!database) database =3D VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE; - return virSecuritySELinuxRestoreFileLabel(mgr, database); + return virSecuritySELinuxRestoreFileLabel(mgr, database, false); =20 case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: return virSecuritySELinuxRestoreChardevLabel(mgr, def, @@ -2559,7 +2626,7 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerP= tr mgr, rc =3D -1; =20 if (def->os.loader && def->os.loader->nvram && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram) < 0) + virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, fal= se) < 0) rc =3D -1; =20 return rc; @@ -2619,7 +2686,7 @@ virSecuritySELinuxRestoreSavedStateLabel(virSecurityM= anagerPtr mgr, if (!secdef || !secdef->relabel) return 0; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, savefile); + return virSecuritySELinuxRestoreFileLabel(mgr, savefile, false); } =20 =20 @@ -3214,7 +3281,7 @@ virSecuritySELinuxRestoreFileLabels(virSecurityManage= rPtr mgr, char *filename =3D NULL; DIR *dir; =20 - if ((ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path))) + if ((ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false))) return ret; =20 if (!virFileIsDir(path)) @@ -3231,7 +3298,7 @@ virSecuritySELinuxRestoreFileLabels(virSecurityManage= rPtr mgr, ret =3D -1; break; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, filename); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, filename, false); VIR_FREE(filename); if (ret < 0) break; --=20 2.18.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list