A new api to help set/restore the shmem device label. Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx> --- src/libvirt_private.syms | 2 + src/security/security_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++ src/security/security_driver.h | 9 ++++ src/security/security_manager.c | 35 ++++++++++++++ src/security/security_manager.h | 6 +++ src/security/security_nop.c | 19 ++++++++ src/security/security_selinux.c | 97 ++++++++++++++++++++++++++++++++++++++ src/security/security_stack.c | 39 ++++++++++++++++ 8 files changed, 307 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e25ef6b..620bd17 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1046,6 +1046,7 @@ virSecurityManagerRestoreDiskLabel; virSecurityManagerRestoreHostdevLabel; virSecurityManagerRestoreImageLabel; virSecurityManagerRestoreSavedStateLabel; +virSecurityManagerRestoreShmemLabel; virSecurityManagerSetAllLabel; virSecurityManagerSetChildProcessLabel; virSecurityManagerSetDaemonSocketLabel; @@ -1056,6 +1057,7 @@ virSecurityManagerSetImageFDLabel; virSecurityManagerSetImageLabel; virSecurityManagerSetProcessLabel; virSecurityManagerSetSavedStateLabel; +virSecurityManagerSetShmemLabel; virSecurityManagerSetSocketLabel; virSecurityManagerSetTapFDLabel; virSecurityManagerStackAddNested; diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 864d75b..a6b4035 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -39,6 +39,7 @@ #include "virstoragefile.h" #include "virstring.h" #include "virutil.h" +#include "virshm.h" #define VIR_FROM_THIS VIR_FROM_SECURITY @@ -930,6 +931,94 @@ virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr, static int +virSecurityDACSetShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem) +{ + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityLabelDefPtr seclabel = NULL; + virSecurityDeviceLabelDefPtr shmem_seclabel = NULL; + char *tmppath = NULL; + uid_t user; + gid_t group; + + if (!priv->dynamicOwnership) + return 0; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); + if (seclabel && !seclabel->relabel) + return 0; + + shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, + SECURITY_DAC_NAME); + if (shmem_seclabel && !shmem_seclabel->relabel) + return 0; + + if (shmem_seclabel && shmem_seclabel->label) { + if (virParseOwnershipIds(shmem_seclabel->label, &user, &group) < 0) + return -1; + } else { + if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0) + return -1; + } + + if (shmem->server.enabled) + return virSecurityDACSetOwnership(shmem->server.chr.data.nix.path, + user, group); + + if (virShmBuildPath(shmem->name, &tmppath) < 0) + return -1; + + if (virSecurityDACSetOwnership(tmppath, user, group) < 0) { + VIR_FREE(tmppath); + return -1; + } + VIR_FREE(tmppath); + return 0; +} + + +static int +virSecurityDACRestoreShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem) +{ + virSecurityDeviceLabelDefPtr shmem_seclabel = NULL; + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityLabelDefPtr secdef = NULL; + char *tmppath = NULL; + + if (!priv->dynamicOwnership) + return 0; + + if (shmem->shareable) + return 0; + + secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); + if (secdef && !secdef->relabel) + return 0; + + shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, SECURITY_DAC_NAME); + + if (shmem_seclabel && !shmem_seclabel->relabel) + return 0; + + if (shmem->server.enabled) + return virSecurityDACRestoreChardevLabel(mgr, def, NULL, &shmem->server.chr); + + if (virShmBuildPath(shmem->name, &tmppath) < 0) + return -1; + + if (virSecurityDACRestoreSecurityFileLabel(tmppath) < 0) { + VIR_FREE(tmppath); + return -1; + } + VIR_FREE(tmppath); + return 0; +} + + +static int virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, bool migrated) @@ -961,6 +1050,10 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr, migrated) < 0) rc = -1; } + for (i = 0; i < def->nshmems; i++) { + if (virSecurityDACRestoreShmemLabel(mgr, def, def->shmems[i])) + rc = -1; + } if (virDomainChrDefForeach(def, false, @@ -1038,6 +1131,10 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr, NULL) < 0) return -1; } + for (i = 0; i < def->nshmems; i++) { + if (virSecurityDACSetShmemLabel(mgr, def, def->shmems[i])) + return -1; + } if (virDomainChrDefForeach(def, true, @@ -1461,4 +1558,7 @@ virSecurityDriver virSecurityDriverDAC = { .getBaseLabel = virSecurityDACGetBaseLabel, .domainSetDirLabel = virSecurityDACDomainSetDirLabel, + + .domainSetSecurityShmemLabel = virSecurityDACSetShmemLabel, + .domainRestoreSecurityShmemLabel = virSecurityDACRestoreShmemLabel, }; diff --git a/src/security/security_driver.h b/src/security/security_driver.h index 784b0de..9fab688 100644 --- a/src/security/security_driver.h +++ b/src/security/security_driver.h @@ -121,6 +121,12 @@ typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr, typedef int (*virSecurityDomainSetDirLabel) (virSecurityManagerPtr mgr, virDomainDefPtr def, const char *path); +typedef int (*virSecurityDomainSetShmemLabel) (virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem); +typedef int (*virSecurityDomainRestoreShmemLabel) (virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem); struct _virSecurityDriver { @@ -173,6 +179,9 @@ struct _virSecurityDriver { virSecurityDriverGetBaseLabel getBaseLabel; virSecurityDomainSetDirLabel domainSetDirLabel; + + virSecurityDomainSetShmemLabel domainSetSecurityShmemLabel; + virSecurityDomainRestoreShmemLabel domainRestoreSecurityShmemLabel; }; virSecurityDriverPtr virSecurityDriverLookup(const char *name, diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 1098558..fec73ec 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -1008,3 +1008,38 @@ virSecurityManagerDomainSetDirLabel(virSecurityManagerPtr mgr, return 0; } + +int +virSecurityManagerRestoreShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem) +{ + if (mgr->drv->domainRestoreSecurityShmemLabel) { + int ret; + virObjectLock(mgr); + ret = mgr->drv->domainRestoreSecurityShmemLabel(mgr, vm, shmem); + virObjectUnlock(mgr); + return ret; + } + + virReportUnsupportedError(); + return -1; +} + + +int +virSecurityManagerSetShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem) +{ + if (mgr->drv->domainSetSecurityShmemLabel) { + int ret; + virObjectLock(mgr); + ret = mgr->drv->domainSetSecurityShmemLabel(mgr, vm, shmem); + virObjectUnlock(mgr); + return ret; + } + + virReportUnsupportedError(); + return -1; +} diff --git a/src/security/security_manager.h b/src/security/security_manager.h index 78f34a0..c12e6e4 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -149,6 +149,12 @@ int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr, int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm, virStorageSourcePtr src); +int virSecurityManagerRestoreShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem); +int virSecurityManagerSetShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem); int virSecurityManagerDomainSetDirLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm, diff --git a/src/security/security_nop.c b/src/security/security_nop.c index 951125d..fd786d7 100644 --- a/src/security/security_nop.c +++ b/src/security/security_nop.c @@ -236,6 +236,22 @@ virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, return 0; } +static int +virSecuritySetShmemLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainShmemDefPtr shmem ATTRIBUTE_UNUSED) +{ + return 0; +} + +static int +virSecurityRestoreShmemLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainShmemDefPtr shmem ATTRIBUTE_UNUSED) +{ + return 0; +} + virSecurityDriver virSecurityDriverNop = { .privateDataLen = 0, @@ -282,4 +298,7 @@ virSecurityDriver virSecurityDriverNop = { .domainGetSecurityMountOptions = virSecurityDomainGetMountOptionsNop, .getBaseLabel = virSecurityGetBaseLabel, + + .domainSetSecurityShmemLabel = virSecuritySetShmemLabel, + .domainRestoreSecurityShmemLabel = virSecurityRestoreShmemLabel, }; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index d2e5aa2..02495f8 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -46,6 +46,7 @@ #include "virconf.h" #include "virtpm.h" #include "virstring.h" +#include "virshm.h" #define VIR_FROM_THIS VIR_FROM_SECURITY @@ -1888,6 +1889,46 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def, } +static int +virSecuritySELinuxRestoreShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem) +{ + virSecurityLabelDefPtr seclabel; + virSecurityDeviceLabelDefPtr shmem_seclabel = NULL; + + if (shmem->shareable) + return 0; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); + if (!seclabel || !seclabel->relabel) + return 0; + + shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, + SECURITY_SELINUX_NAME); + + if (shmem_seclabel && !shmem_seclabel->relabel) + return 0; + + if (shmem->server.enabled) { + return virSecuritySELinuxRestoreSecurityFileLabel(mgr, + shmem->server.chr.data.nix.path); + } else { + char *tmppath = NULL; + + if (virShmBuildPath(shmem->name, &tmppath) < 0) + return -1; + + if (virSecuritySELinuxRestoreSecurityFileLabel(mgr, tmppath) < 0) { + VIR_FREE(tmppath); + return -1; + } + VIR_FREE(tmppath); + return 0; + } +} + + static const char * virSecuritySELinuxGetBaseLabel(virSecurityManagerPtr mgr, int virtType) { @@ -1936,6 +1977,10 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr, migrated) < 0) rc = -1; } + for (i = 0; i < def->nshmems; i++) { + if (virSecuritySELinuxRestoreShmemLabel(mgr, def, def->shmems[i]) < 0) + rc = -1; + } if (virDomainChrDefForeach(def, false, @@ -2284,6 +2329,49 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def, static int +virSecuritySELinuxSetShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainShmemDefPtr shmem) +{ + virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); + char *imagelabel = NULL; + virSecurityLabelDefPtr seclabel; + virSecurityDeviceLabelDefPtr shmem_seclabel = NULL; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); + if (!seclabel || !seclabel->relabel) + return 0; + + shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, SECURITY_SELINUX_NAME); + + if (shmem_seclabel && !shmem_seclabel->relabel) + return 0; + + if (shmem_seclabel) + imagelabel = shmem_seclabel->label; + if (!imagelabel) + imagelabel = shmem->shareable ? data->file_context : seclabel->imagelabel; + + if (shmem->server.enabled) { + return virSecuritySELinuxSetFilecon(shmem->server.chr.data.nix.path, + imagelabel); + } else { + char *tmppath = NULL; + + if (virShmBuildPath(shmem->name, &tmppath) < 0) + return -1; + + if (virSecuritySELinuxSetFilecon(tmppath, imagelabel) < 0) { + VIR_FREE(tmppath); + return -1; + } + VIR_FREE(tmppath); + return 0; + } +} + + +static int virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, const char *stdin_path) @@ -2318,6 +2406,12 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr, NULL) < 0) return -1; } + + for (i = 0; i < def->nshmems; i++) { + if (virSecuritySELinuxSetShmemLabel(mgr, def, def->shmems[i]) < 0) + return -1; + } + if (def->tpm) { if (virSecuritySELinuxSetSecurityTPMFileLabel(mgr, def, def->tpm) < 0) @@ -2565,4 +2659,7 @@ virSecurityDriver virSecurityDriverSELinux = { .getBaseLabel = virSecuritySELinuxGetBaseLabel, .domainSetDirLabel = virSecuritySELinuxDomainSetDirLabel, + + .domainSetSecurityShmemLabel = virSecuritySELinuxSetShmemLabel, + .domainRestoreSecurityShmemLabel = virSecuritySELinuxRestoreShmemLabel, }; diff --git a/src/security/security_stack.c b/src/security/security_stack.c index 8d9560d..cecde88 100644 --- a/src/security/security_stack.c +++ b/src/security/security_stack.c @@ -617,6 +617,42 @@ virSecurityStackDomainSetDirLabel(virSecurityManagerPtr mgr, return rc; } +static int +virSecurityStackSetShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem) +{ + virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityStackItemPtr item = priv->itemsHead; + int rc = 0; + + for (; item; item = item->next) { + if (virSecurityManagerSetShmemLabel(item->securityManager, + vm, shmem) < 0) + rc = -1; + } + + return rc; +} + +static int +virSecurityStackRestoreShmemLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virDomainShmemDefPtr shmem) +{ + virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityStackItemPtr item = priv->itemsHead; + int rc = 0; + + for (; item; item = item->next) { + if (virSecurityManagerRestoreShmemLabel(item->securityManager, + vm, shmem) < 0) + rc = -1; + } + + return rc; +} + virSecurityDriver virSecurityDriverStack = { .privateDataLen = sizeof(virSecurityStackData), .name = "stack", @@ -668,4 +704,7 @@ virSecurityDriver virSecurityDriverStack = { .getBaseLabel = virSecurityStackGetBaseLabel, .domainSetDirLabel = virSecurityStackDomainSetDirLabel, + + .domainSetSecurityShmemLabel = virSecurityStackSetShmemLabel, + .domainRestoreSecurityShmemLabel = virSecurityStackRestoreShmemLabel, }; -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list