A new api to help set/restore the shmem device
label.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
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