Whenever a security driver wants to change label of some path, it should let virUdevMgr module know so that it can update its internal database too. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 2 ++ src/security/security_dac.c | 36 ++++++++++++++++++++++++++++--- src/security/security_manager.c | 16 ++++++++++++++ src/security/security_manager.h | 5 +++++ src/security/security_selinux.c | 47 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a0de4e9..66df1f7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1143,6 +1143,7 @@ virSecurityManagerGetModel; virSecurityManagerGetMountOptions; virSecurityManagerGetNested; virSecurityManagerGetProcessLabel; +virSecurityManagerGetUdevManager; virSecurityManagerNew; virSecurityManagerNewDAC; virSecurityManagerNewStack; @@ -1167,6 +1168,7 @@ virSecurityManagerSetProcessLabel; virSecurityManagerSetSavedStateLabel; virSecurityManagerSetSocketLabel; virSecurityManagerSetTapFDLabel; +virSecurityManagerSetUdevManager; virSecurityManagerStackAddNested; virSecurityManagerVerify; diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 7f17124..54e59c7 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -356,7 +356,11 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, gid_t gid) { virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr); + virSecurityDeviceLabelDefPtr seclabel = NULL; + char *label = NULL; struct stat sb; + int ret = -1; if (!path && src && src->path && virStorageSourceIsLocalStorage(src)) @@ -365,14 +369,36 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, if (path) { if (stat(path, &sb) < 0) { virReportSystemError(errno, _("unable to stat: %s"), path); - return -1; + return ret; } if (virSecurityDACRememberLabel(priv, path, sb.st_uid, sb.st_gid) < 0) - return -1; + return ret; + + if (udevMgr) { + if (virAsprintf(&label, "%u %u", + (unsigned int) uid, + (unsigned int) gid) < 0) + goto cleanup; + + if (!(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_DAC_NAME, label))) + goto cleanup; + VIR_FREE(label); + } } - return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid); + if (virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid) < 0) + goto cleanup; + + if (udevMgr && path && + virUdevMgrAddLabel(udevMgr, path, seclabel) < 0) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(label); + virSecurityDeviceLabelDefFree(seclabel); + return ret; } @@ -382,6 +408,7 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr, const char *path) { virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr); int rv; uid_t uid = 0; /* By default return to root:root */ gid_t gid = 0; @@ -399,6 +426,9 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr, return -1; if (rv > 0) return 0; + + if (udevMgr) + virUdevMgrRemoveAllLabels(udevMgr, path); } return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid); diff --git a/src/security/security_manager.c b/src/security/security_manager.c index ecb4a40..2f07d6a 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -39,6 +39,7 @@ struct _virSecurityManager { virSecurityDriverPtr drv; unsigned int flags; const char *virtDriver; + virUdevMgrPtr udevMgr; void *privateData; }; @@ -1001,3 +1002,18 @@ virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr, return 0; } + + +void +virSecurityManagerSetUdevManager(virSecurityManagerPtr mgr, + virUdevMgrPtr udevMgr) +{ + mgr->udevMgr = virObjectRef(udevMgr); +} + + +virUdevMgrPtr +virSecurityManagerGetUdevManager(virSecurityManagerPtr mgr) +{ + return mgr->udevMgr; +} diff --git a/src/security/security_manager.h b/src/security/security_manager.h index 4cbc2d8..8f565f7 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -26,6 +26,7 @@ # include "domain_conf.h" # include "vircommand.h" # include "virstoragefile.h" +# include "virudev.h" typedef struct _virSecurityManager virSecurityManager; typedef virSecurityManager *virSecurityManagerPtr; @@ -164,4 +165,8 @@ int virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm, const char *path); +void virSecurityManagerSetUdevManager(virSecurityManagerPtr mgr, + virUdevMgrPtr udevMgr); +virUdevMgrPtr virSecurityManagerGetUdevManager(virSecurityManagerPtr mgr); + #endif /* VIR_SECURITY_MANAGER_H__ */ diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 5dad22c..c85f500 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -947,7 +947,24 @@ virSecuritySELinuxSetFileconOptional(virSecurityManagerPtr mgr, const char *path, char *tcon) { bool privileged = virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged); + virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr); + virSecurityDeviceLabelDefPtr seclabel = NULL; + int rc; + + if (udevMgr && + !(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_SELINUX_NAME, tcon))) + return -1; + + rc = virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged); + + if (udevMgr && + virUdevMgrAddLabel(udevMgr, path, seclabel) < 0) { + virSecurityDeviceLabelDefFree(seclabel); + return -1; + } + + virSecurityDeviceLabelDefFree(seclabel); + return rc; } static int @@ -955,7 +972,24 @@ virSecuritySELinuxSetFilecon(virSecurityManagerPtr mgr, const char *path, char *tcon) { bool privileged = virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, false, privileged); + virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr); + virSecurityDeviceLabelDefPtr seclabel = NULL; + int rc; + + if (udevMgr && + !(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_SELINUX_NAME, tcon))) + return -1; + + rc = virSecuritySELinuxSetFileconHelper(path, tcon, false, privileged); + + if (udevMgr && + virUdevMgrAddLabel(udevMgr, path, seclabel) < 0) { + virSecurityDeviceLabelDefFree(seclabel); + return -1; + } + + virSecurityDeviceLabelDefFree(seclabel); + return rc; } static int @@ -1018,6 +1052,8 @@ static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, const char *path) { + virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr); + bool privileged = virSecurityManagerGetPrivileged(mgr); struct stat buf; security_context_t fcon = NULL; int rc = -1; @@ -1038,6 +1074,11 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, goto err; } + if (udevMgr) { + virUdevMgrRemoveAllLabels(udevMgr, path); + virUdevMgrRemoveAllLabels(udevMgr, newpath); + } + if (stat(newpath, &buf) != 0) { VIR_WARN("cannot stat %s: %s", newpath, virStrerror(errno, ebuf, sizeof(ebuf))); @@ -1051,7 +1092,7 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, VIR_WARN("cannot lookup default selinux label for %s", newpath); rc = 0; } else { - rc = virSecuritySELinuxSetFilecon(mgr, newpath, fcon); + rc = virSecuritySELinuxSetFileconHelper(newpath, fcon, false, privileged); } err: -- 2.8.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list