diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 16eb5d3351..e59ea4c02c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -924,6 +924,7 @@ virSecurityManagerReserveLabel; virSecurityManagerRestoreAllLabel; virSecurityManagerRestoreDiskLabel; virSecurityManagerRestoreHostdevLabel; +virSecurityManagerRestoreImageLabel; virSecurityManagerRestoreSavedStateLabel; virSecurityManagerSetAllLabel; virSecurityManagerSetChildProcessLabel; @@ -932,6 +933,7 @@ virSecurityManagerSetDiskLabel; virSecurityManagerSetHostdevLabel; virSecurityManagerSetHugepages; virSecurityManagerSetImageFDLabel; +virSecurityManagerSetImageLabel; virSecurityManagerSetProcessLabel; virSecurityManagerSetSavedStateLabel; virSecurityManagerSetSocketLabel; diff --git a/src/security/security_driver.h b/src/security/security_driver.h index 062dc8f8bd..f0dca09177 100644 --- a/src/security/security_driver.h +++ b/src/security/security_driver.h @@ -112,6 +112,13 @@ typedef char *(*virSecurityDomainGetMountOptions) (virSecurityManagerPtr mgr, typedef int (*virSecurityDomainSetHugepages) (virSecurityManagerPtr mgr, virDomainDefPtr def, const char *path); +typedef int (*virSecurityDomainSetImageLabel) (virSecurityManagerPtr mgr, + virDomainDefPtr def, + virStorageSourcePtr src); +typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr, + virDomainDefPtr def, + virStorageSourcePtr src); + struct _virSecurityDriver { size_t privateDataLen; @@ -130,6 +137,9 @@ struct _virSecurityDriver { virSecurityDomainSetDiskLabel domainSetSecurityDiskLabel; virSecurityDomainRestoreDiskLabel domainRestoreSecurityDiskLabel; + virSecurityDomainSetImageLabel domainSetSecurityImageLabel; + virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel; + virSecurityDomainSetDaemonSocketLabel domainSetSecurityDaemonSocketLabel; virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel; virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel; diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 06e5123db1..16bec5c2b4 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -360,6 +360,34 @@ virSecurityManagerRestoreDiskLabel(virSecurityManagerPtr mgr, } +/** + * virSecurityManagerRestoreImageLabel: + * @mgr: security manager object + * @vm: domain definition object + * @src: disk source definition to operate on + * + * Removes security label from a single storage image. + * + * Returns: 0 on success, -1 on error. + */ +int +virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src) +{ + if (mgr->drv->domainRestoreSecurityImageLabel) { + int ret; + virObjectLock(mgr); + ret = mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, src); + virObjectUnlock(mgr); + return ret; + } + + virReportUnsupportedError(); + return -1; +} + + int virSecurityManagerSetDaemonSocketLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) @@ -440,6 +468,34 @@ virSecurityManagerSetDiskLabel(virSecurityManagerPtr mgr, } +/** + * virSecurityManagerSetImageLabel: + * @mgr: security manager object + * @vm: domain definition object + * @src: disk source definition to operate on + * + * Labels a single storage image with the configured security label. + * + * Returns: 0 on success, -1 on error. + */ +int +virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src) +{ + if (mgr->drv->domainSetSecurityImageLabel) { + int ret; + virObjectLock(mgr); + ret = mgr->drv->domainSetSecurityImageLabel(mgr, vm, src); + virObjectUnlock(mgr); + return ret; + } + + virReportUnsupportedError(); + return -1; +} + + int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm, diff --git a/src/security/security_manager.h b/src/security/security_manager.h index 8a5fcfb4d5..97b6a2e67f 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -124,4 +124,11 @@ int virSecurityManagerSetHugepages(virSecurityManagerPtr mgr, virDomainDefPtr sec, const char *hugepages_path); +int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src); +int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src); + #endif /* VIR_SECURITY_MANAGER_H__ */ diff --git a/src/security/security_nop.c b/src/security/security_nop.c index b57bf05ec4..951125dcee 100644 --- a/src/security/security_nop.c +++ b/src/security/security_nop.c @@ -220,6 +220,22 @@ virSecurityGetBaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, return NULL; } +static int +virSecurityDomainRestoreImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virStorageSourcePtr src ATTRIBUTE_UNUSED) +{ + return 0; +} + +static int +virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virStorageSourcePtr src ATTRIBUTE_UNUSED) +{ + return 0; +} + virSecurityDriver virSecurityDriverNop = { .privateDataLen = 0, @@ -236,6 +252,9 @@ virSecurityDriver virSecurityDriverNop = { .domainSetSecurityDiskLabel = virSecurityDomainSetDiskLabelNop, .domainRestoreSecurityDiskLabel = virSecurityDomainRestoreDiskLabelNop, + .domainSetSecurityImageLabel = virSecurityDomainSetImageLabelNop, + .domainRestoreSecurityImageLabel = virSecurityDomainRestoreImageLabelNop, + .domainSetSecurityDaemonSocketLabel = virSecurityDomainSetDaemonSocketLabelNop, .domainSetSecuritySocketLabel = virSecurityDomainSetSocketLabelNop, .domainClearSecuritySocketLabel = virSecurityDomainClearSocketLabelNop, diff --git a/src/security/security_stack.c b/src/security/security_stack.c index e3e9c8581d..1ded57b960 100644 --- a/src/security/security_stack.c +++ b/src/security/security_stack.c @@ -564,6 +564,41 @@ virSecurityStackGetBaseLabel(virSecurityManagerPtr mgr, int virtType) virtType); } +static int +virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src) +{ + virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityStackItemPtr item = priv->itemsHead; + int rc = 0; + + for (; item; item = item->next) { + if (virSecurityManagerSetImageLabel(item->securityManager, vm, src) < 0) + rc = -1; + } + + return rc; +} + +static int +virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr, + virDomainDefPtr vm, + virStorageSourcePtr src) +{ + virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityStackItemPtr item = priv->itemsHead; + int rc = 0; + + for (; item; item = item->next) { + if (virSecurityManagerRestoreImageLabel(item->securityManager, + vm, src) < 0) + rc = -1; + } + + return rc; +} + virSecurityDriver virSecurityDriverStack = { .privateDataLen = sizeof(virSecurityStackData), .name = "stack", @@ -581,6 +616,9 @@ virSecurityDriver virSecurityDriverStack = { .domainSetSecurityDiskLabel = virSecurityStackSetSecurityDiskLabel, .domainRestoreSecurityDiskLabel = virSecurityStackRestoreSecurityDiskLabel, + .domainSetSecurityImageLabel = virSecurityStackSetSecurityImageLabel, + .domainRestoreSecurityImageLabel = virSecurityStackRestoreSecurityImageLabel, + .domainSetSecurityDaemonSocketLabel = virSecurityStackSetDaemonSocketLabel, .domainSetSecuritySocketLabel = virSecurityStackSetSocketLabel, .domainClearSecuritySocketLabel = virSecurityStackClearSocketLabel,