mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-26 15:14:42 +00:00
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like if (driver->securityDriver && driver->securityDriver->domainSetSecurityHostdevLabel && driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver, vm, hostdev) < 0) This pair of checks for NULL clutters up the code, making the driver calls 2 lines longer than they really need to be. The goal of the patchset is to change the calling convention to simply if (virSecurityManagerSetHostdevLabel(driver->securityDriver, vm, hostdev) < 0) The first check for 'driver->securityDriver' being NULL is removed by introducing a 'no op' security driver that will always be present if no real driver is enabled. This guarentees driver->securityDriver != NULL. The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel' being non-NULL is hidden in a new abstraction called virSecurityManager. This separates the driver callbacks, from main internal API. The addition of a virSecurityManager object, that is separate from the virSecurityDriver struct also allows for security drivers to carry state / configuration information directly. Thus the DAC/Stack drivers from src/qemu which used to pull config from 'struct qemud_driver' can now be moved into the 'src/security' directory and store their config directly. * src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to use new virSecurityManager APIs * src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h: Move into src/security directory * src/security/security_stack.c, src/security/security_stack.h, src/security/security_dac.c, src/security/security_dac.h: Generic versions of previous QEMU specific drivers * src/security/security_apparmor.c, src/security/security_apparmor.h, src/security/security_driver.c, src/security/security_driver.h, src/security/security_selinux.c, src/security/security_selinux.h: Update to take virSecurityManagerPtr object as the first param in all callbacks * src/security/security_nop.c, src/security/security_nop.h: Stub implementation of all security driver APIs. * src/security/security_manager.h, src/security/security_manager.c: New internal API for invoking security drivers * src/libvirt.c: Add missing debug for security APIs
This commit is contained in:
parent
92d6530106
commit
d6623003c6
@ -61,10 +61,10 @@ src/qemu/qemu_hotplug.c
|
|||||||
src/qemu/qemu_monitor.c
|
src/qemu/qemu_monitor.c
|
||||||
src/qemu/qemu_monitor_json.c
|
src/qemu/qemu_monitor_json.c
|
||||||
src/qemu/qemu_monitor_text.c
|
src/qemu/qemu_monitor_text.c
|
||||||
src/qemu/qemu_security_dac.c
|
|
||||||
src/remote/remote_driver.c
|
src/remote/remote_driver.c
|
||||||
src/secret/secret_driver.c
|
src/secret/secret_driver.c
|
||||||
src/security/security_apparmor.c
|
src/security/security_apparmor.c
|
||||||
|
src/security/security_dac.c
|
||||||
src/security/security_driver.c
|
src/security/security_driver.c
|
||||||
src/security/security_selinux.c
|
src/security/security_selinux.c
|
||||||
src/security/virt-aa-helper.c
|
src/security/virt-aa-helper.c
|
||||||
|
@ -288,11 +288,7 @@ QEMU_DRIVER_SOURCES = \
|
|||||||
qemu/qemu_monitor_json.h \
|
qemu/qemu_monitor_json.h \
|
||||||
qemu/qemu_driver.c qemu/qemu_driver.h \
|
qemu/qemu_driver.c qemu/qemu_driver.h \
|
||||||
qemu/qemu_bridge_filter.c \
|
qemu/qemu_bridge_filter.c \
|
||||||
qemu/qemu_bridge_filter.h \
|
qemu/qemu_bridge_filter.h
|
||||||
qemu/qemu_security_stacked.h \
|
|
||||||
qemu/qemu_security_stacked.c \
|
|
||||||
qemu/qemu_security_dac.h \
|
|
||||||
qemu/qemu_security_dac.c
|
|
||||||
|
|
||||||
XENAPI_DRIVER_SOURCES = \
|
XENAPI_DRIVER_SOURCES = \
|
||||||
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
|
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
|
||||||
@ -390,7 +386,11 @@ NWFILTER_DRIVER_SOURCES = \
|
|||||||
|
|
||||||
# Security framework and drivers for various models
|
# Security framework and drivers for various models
|
||||||
SECURITY_DRIVER_SOURCES = \
|
SECURITY_DRIVER_SOURCES = \
|
||||||
security/security_driver.h security/security_driver.c
|
security/security_driver.h security/security_driver.c \
|
||||||
|
security/security_nop.h security/security_nop.c \
|
||||||
|
security/security_stack.h security/security_stack.c \
|
||||||
|
security/security_dac.h security/security_dac.c \
|
||||||
|
security/security_manager.h security/security_manager.c
|
||||||
|
|
||||||
SECURITY_DRIVER_SELINUX_SOURCES = \
|
SECURITY_DRIVER_SELINUX_SOURCES = \
|
||||||
security/security_selinux.h security/security_selinux.c
|
security/security_selinux.h security/security_selinux.c
|
||||||
|
@ -5642,6 +5642,8 @@ virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
|
|||||||
{
|
{
|
||||||
virConnectPtr conn;
|
virConnectPtr conn;
|
||||||
|
|
||||||
|
VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);
|
||||||
|
|
||||||
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
virDispatchError(NULL);
|
virDispatchError(NULL);
|
||||||
@ -5684,6 +5686,8 @@ error:
|
|||||||
int
|
int
|
||||||
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
|
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
|
||||||
{
|
{
|
||||||
|
DEBUG("conn=%p secmodel=%p", conn, secmodel);
|
||||||
|
|
||||||
if (!VIR_IS_CONNECT(conn)) {
|
if (!VIR_IS_CONNECT(conn)) {
|
||||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||||
virDispatchError(NULL);
|
virDispatchError(NULL);
|
||||||
|
@ -701,13 +701,33 @@ virSecretDefParseFile;
|
|||||||
virSecretDefParseString;
|
virSecretDefParseString;
|
||||||
|
|
||||||
|
|
||||||
# security.h
|
# security_driver.h
|
||||||
virSecurityDriverGetDOI;
|
virSecurityDriverLookup;
|
||||||
virSecurityDriverGetModel;
|
|
||||||
virSecurityDriverInit;
|
|
||||||
virSecurityDriverSetDOI;
|
# security_manager.h
|
||||||
virSecurityDriverStartup;
|
virSecurityManagerClearSocketLabel;
|
||||||
virSecurityDriverVerify;
|
virSecurityManagerFree;
|
||||||
|
virSecurityManagerGenLabel;
|
||||||
|
virSecurityManagerGetDOI;
|
||||||
|
virSecurityManagerGetModel;
|
||||||
|
virSecurityManagerGetProcessLabel;
|
||||||
|
virSecurityManagerNew;
|
||||||
|
virSecurityManagerNewStack;
|
||||||
|
virSecurityManagerNewDAC;
|
||||||
|
virSecurityManagerReleaseLabel;
|
||||||
|
virSecurityManagerReserveLabel;
|
||||||
|
virSecurityManagerRestoreImageLabel;
|
||||||
|
virSecurityManagerRestoreAllLabel;
|
||||||
|
virSecurityManagerRestoreHostdevLabel;
|
||||||
|
virSecurityManagerRestoreSavedStateLabel;
|
||||||
|
virSecurityManagerSetAllLabel;
|
||||||
|
virSecurityManagerSetImageLabel;
|
||||||
|
virSecurityManagerSetHostdevLabel;
|
||||||
|
virSecurityManagerSetProcessLabel;
|
||||||
|
virSecurityManagerSetSavedStateLabel;
|
||||||
|
virSecurityManagerSetSocketLabel;
|
||||||
|
virSecurityManagerVerify;
|
||||||
|
|
||||||
|
|
||||||
# storage_conf.h
|
# storage_conf.h
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
# include "domain_conf.h"
|
# include "domain_conf.h"
|
||||||
# include "domain_event.h"
|
# include "domain_event.h"
|
||||||
# include "threads.h"
|
# include "threads.h"
|
||||||
# include "security/security_driver.h"
|
# include "security/security_manager.h"
|
||||||
# include "cgroup.h"
|
# include "cgroup.h"
|
||||||
# include "pci.h"
|
# include "pci.h"
|
||||||
# include "cpu_conf.h"
|
# include "cpu_conf.h"
|
||||||
@ -114,9 +114,7 @@ struct qemud_driver {
|
|||||||
int domainEventDispatching;
|
int domainEventDispatching;
|
||||||
|
|
||||||
char *securityDriverName;
|
char *securityDriverName;
|
||||||
virSecurityDriverPtr securityDriver;
|
virSecurityManagerPtr securityManager;
|
||||||
virSecurityDriverPtr securityPrimaryDriver;
|
|
||||||
virSecurityDriverPtr securitySecondaryDriver;
|
|
||||||
|
|
||||||
char *saveImageFormat;
|
char *saveImageFormat;
|
||||||
char *dumpImageFormat;
|
char *dumpImageFormat;
|
||||||
|
@ -73,8 +73,6 @@
|
|||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "hostusb.h"
|
#include "hostusb.h"
|
||||||
#include "processinfo.h"
|
#include "processinfo.h"
|
||||||
#include "qemu_security_stacked.h"
|
|
||||||
#include "qemu_security_dac.h"
|
|
||||||
#include "libvirt_internal.h"
|
#include "libvirt_internal.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "cpu/cpu.h"
|
#include "cpu/cpu.h"
|
||||||
@ -861,10 +859,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
|
|||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetSocketLabel(driver->securityManager, vm) < 0) {
|
||||||
driver->securityDriver->domainSetSecuritySocketLabel &&
|
|
||||||
driver->securityDriver->domainSetSecuritySocketLabel
|
|
||||||
(driver->securityDriver,vm) < 0) {
|
|
||||||
VIR_ERROR(_("Failed to set security context for monitor for %s"),
|
VIR_ERROR(_("Failed to set security context for monitor for %s"),
|
||||||
vm->def->name);
|
vm->def->name);
|
||||||
goto error;
|
goto error;
|
||||||
@ -882,10 +877,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
|
|||||||
if (priv->mon == NULL)
|
if (priv->mon == NULL)
|
||||||
virDomainObjUnref(vm);
|
virDomainObjUnref(vm);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerClearSocketLabel(driver->securityManager, vm) < 0) {
|
||||||
driver->securityDriver->domainClearSecuritySocketLabel &&
|
|
||||||
driver->securityDriver->domainClearSecuritySocketLabel
|
|
||||||
(driver->securityDriver,vm) < 0) {
|
|
||||||
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
|
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
|
||||||
vm->def->name);
|
vm->def->name);
|
||||||
goto error;
|
goto error;
|
||||||
@ -954,10 +946,7 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaq
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerReserveLabel(driver->securityManager, obj) < 0)
|
||||||
driver->securityDriver->domainReserveSecurityLabel &&
|
|
||||||
driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver,
|
|
||||||
obj) < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (qemudVMFiltersInstantiate(conn, obj->def))
|
if (qemudVMFiltersInstantiate(conn, obj->def))
|
||||||
@ -995,35 +984,34 @@ qemuReconnectDomains(virConnectPtr conn, struct qemud_driver *driver)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemudSecurityInit(struct qemud_driver *qemud_drv)
|
qemuSecurityInit(struct qemud_driver *driver)
|
||||||
{
|
{
|
||||||
int ret;
|
virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
|
||||||
virSecurityDriverPtr security_drv;
|
driver->allowDiskFormatProbing);
|
||||||
|
if (!mgr)
|
||||||
|
goto error;
|
||||||
|
|
||||||
qemuSecurityStackedSetDriver(qemud_drv);
|
if (driver->privileged) {
|
||||||
qemuSecurityDACSetDriver(qemud_drv);
|
virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
|
||||||
|
driver->group,
|
||||||
|
driver->allowDiskFormatProbing,
|
||||||
|
driver->dynamicOwnership);
|
||||||
|
if (!dac)
|
||||||
|
goto error;
|
||||||
|
|
||||||
ret = virSecurityDriverStartup(&security_drv,
|
if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
|
||||||
qemud_drv->securityDriverName,
|
dac)))
|
||||||
qemud_drv->allowDiskFormatProbing);
|
goto error;
|
||||||
if (ret == -1) {
|
|
||||||
VIR_ERROR0(_("Failed to start security driver"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No primary security driver wanted to be enabled: just setup
|
|
||||||
* the DAC driver on its own */
|
|
||||||
if (ret == -2) {
|
|
||||||
qemud_drv->securityDriver = &qemuDACSecurityDriver;
|
|
||||||
VIR_INFO0(_("No security driver available"));
|
|
||||||
} else {
|
} else {
|
||||||
qemud_drv->securityPrimaryDriver = security_drv;
|
driver->securityManager = mgr;
|
||||||
qemud_drv->securitySecondaryDriver = &qemuDACSecurityDriver;
|
|
||||||
qemud_drv->securityDriver = &qemuStackedSecurityDriver;
|
|
||||||
VIR_INFO("Initialized security driver %s", security_drv->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_ERROR0(_("Failed to initialize security drivers"));
|
||||||
|
virSecurityManagerFree(mgr);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1057,21 +1045,20 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Security driver data */
|
/* Security driver data */
|
||||||
if (driver->securityPrimaryDriver) {
|
const char *doi, *model;
|
||||||
const char *doi, *model;
|
|
||||||
|
|
||||||
doi = virSecurityDriverGetDOI(driver->securityPrimaryDriver);
|
|
||||||
model = virSecurityDriverGetModel(driver->securityPrimaryDriver);
|
|
||||||
|
|
||||||
|
doi = virSecurityManagerGetDOI(driver->securityManager);
|
||||||
|
model = virSecurityManagerGetModel(driver->securityManager);
|
||||||
|
if (STRNEQ(model, "none")) {
|
||||||
if (!(caps->host.secModel.model = strdup(model)))
|
if (!(caps->host.secModel.model = strdup(model)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (!(caps->host.secModel.doi = strdup(doi)))
|
if (!(caps->host.secModel.doi = strdup(doi)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
VIR_DEBUG("Initialized caps for security driver \"%s\" with "
|
|
||||||
"DOI \"%s\"", model, doi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("Initialized caps for security driver \"%s\" with "
|
||||||
|
"DOI \"%s\"", model, doi);
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
@ -1336,7 +1323,7 @@ qemudStartup(int privileged) {
|
|||||||
}
|
}
|
||||||
VIR_FREE(driverConf);
|
VIR_FREE(driverConf);
|
||||||
|
|
||||||
if (qemudSecurityInit(qemu_driver) < 0)
|
if (qemuSecurityInit(qemu_driver) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((qemu_driver->caps = qemuCreateCapabilities(NULL,
|
if ((qemu_driver->caps = qemuCreateCapabilities(NULL,
|
||||||
@ -1555,10 +1542,11 @@ qemudShutdown(void) {
|
|||||||
VIR_FREE(qemu_driver->spicePassword);
|
VIR_FREE(qemu_driver->spicePassword);
|
||||||
VIR_FREE(qemu_driver->hugetlbfs_mount);
|
VIR_FREE(qemu_driver->hugetlbfs_mount);
|
||||||
VIR_FREE(qemu_driver->hugepage_path);
|
VIR_FREE(qemu_driver->hugepage_path);
|
||||||
VIR_FREE(qemu_driver->securityDriverName);
|
|
||||||
VIR_FREE(qemu_driver->saveImageFormat);
|
VIR_FREE(qemu_driver->saveImageFormat);
|
||||||
VIR_FREE(qemu_driver->dumpImageFormat);
|
VIR_FREE(qemu_driver->dumpImageFormat);
|
||||||
|
|
||||||
|
virSecurityManagerFree(qemu_driver->securityManager);
|
||||||
|
|
||||||
ebtablesContextFree(qemu_driver->ebtables);
|
ebtablesContextFree(qemu_driver->ebtables);
|
||||||
|
|
||||||
if (qemu_driver->cgroupDeviceACL) {
|
if (qemu_driver->cgroupDeviceACL) {
|
||||||
@ -2573,9 +2561,7 @@ static int qemudSecurityHook(void *data) {
|
|||||||
if (qemudInitCpuAffinity(h->vm) < 0)
|
if (qemudInitCpuAffinity(h->vm) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (h->driver->securityDriver &&
|
if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm) < 0)
|
||||||
h->driver->securityDriver->domainSetSecurityProcessLabel &&
|
|
||||||
h->driver->securityDriver->domainSetSecurityProcessLabel(h->driver->securityDriver, h->vm) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2660,22 +2646,16 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
/* If you are using a SecurityDriver with dynamic labelling,
|
/* If you are using a SecurityDriver with dynamic labelling,
|
||||||
then generate a security label for isolation */
|
then generate a security label for isolation */
|
||||||
DEBUG0("Generating domain security label (if required)");
|
DEBUG0("Generating domain security label (if required)");
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerGenLabel(driver->securityManager, vm) < 0) {
|
||||||
driver->securityDriver->domainGenSecurityLabel) {
|
qemuDomainSecurityLabelAudit(vm, false);
|
||||||
ret = driver->securityDriver->domainGenSecurityLabel(driver->securityDriver,
|
|
||||||
vm);
|
|
||||||
qemuDomainSecurityLabelAudit(vm, ret >= 0);
|
|
||||||
if (ret < 0)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG0("Generating setting domain security labels (if required)");
|
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainSetSecurityAllLabel &&
|
|
||||||
driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver,
|
|
||||||
vm, stdin_path) < 0) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
qemuDomainSecurityLabelAudit(vm, true);
|
||||||
|
|
||||||
|
DEBUG0("Generating setting domain security labels (if required)");
|
||||||
|
if (virSecurityManagerSetAllLabel(driver->securityManager,
|
||||||
|
vm, stdin_path) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
/* Ensure no historical cgroup for this VM is lying around bogus
|
/* Ensure no historical cgroup for this VM is lying around bogus
|
||||||
* settings */
|
* settings */
|
||||||
@ -3057,14 +3037,9 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reset Security Labels */
|
/* Reset Security Labels */
|
||||||
if (driver->securityDriver &&
|
virSecurityManagerRestoreAllLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityAllLabel)
|
vm, migrated);
|
||||||
driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver,
|
virSecurityManagerReleaseLabel(driver->securityManager, vm);
|
||||||
vm, migrated);
|
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainReleaseSecurityLabel)
|
|
||||||
driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver,
|
|
||||||
vm);
|
|
||||||
|
|
||||||
/* Clear out dynamically assigned labels */
|
/* Clear out dynamically assigned labels */
|
||||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||||
@ -3568,7 +3543,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
|
|||||||
VIR_DOMAIN_XML_INACTIVE)))
|
VIR_DOMAIN_XML_INACTIVE)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virSecurityDriverVerify(def) < 0)
|
if (virSecurityManagerVerify(driver->securityManager, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
||||||
@ -4471,10 +4446,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((!bypassSecurityDriver) &&
|
if ((!bypassSecurityDriver) &&
|
||||||
driver->securityDriver &&
|
virSecurityManagerSetSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
|
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
|
||||||
@ -4507,10 +4480,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
if ((!bypassSecurityDriver) &&
|
if ((!bypassSecurityDriver) &&
|
||||||
driver->securityDriver &&
|
virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
VIR_WARN("failed to restore save state label on %s", path);
|
VIR_WARN("failed to restore save state label on %s", path);
|
||||||
|
|
||||||
if (cgroup != NULL) {
|
if (cgroup != NULL) {
|
||||||
@ -4552,10 +4523,8 @@ endjob:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((!bypassSecurityDriver) &&
|
if ((!bypassSecurityDriver) &&
|
||||||
driver->securityDriver &&
|
virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
VIR_WARN("failed to restore save state label on %s", path);
|
VIR_WARN("failed to restore save state label on %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4779,10 +4748,8 @@ static int doCoreDump(struct qemud_driver *driver,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
@ -4814,10 +4781,8 @@ static int doCoreDump(struct qemud_driver *driver,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -5434,10 +5399,8 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec
|
|||||||
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
|
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
|
||||||
*/
|
*/
|
||||||
if (virDomainObjIsActive(vm)) {
|
if (virDomainObjIsActive(vm)) {
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerGetProcessLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainGetSecurityProcessLabel &&
|
vm, seclabel) < 0) {
|
||||||
driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver,
|
|
||||||
vm, seclabel) < 0) {
|
|
||||||
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("Failed to get security label"));
|
"%s", _("Failed to get security label"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -5461,10 +5424,12 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
if (!driver->securityPrimaryDriver) {
|
memset(secmodel, 0, sizeof(*secmodel));
|
||||||
memset(secmodel, 0, sizeof (*secmodel));
|
|
||||||
|
/* NULL indicates no driver, which we treat as
|
||||||
|
* success, but simply return no data in *secmodel */
|
||||||
|
if (driver->caps->host.secModel.model == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
p = driver->caps->host.secModel.model;
|
p = driver->caps->host.secModel.model;
|
||||||
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
|
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
|
||||||
@ -5840,10 +5805,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel &&
|
vm, path) < 0)
|
||||||
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
|
|
||||||
vm, path) == -1)
|
|
||||||
VIR_WARN("failed to restore save state label on %s", path);
|
VIR_WARN("failed to restore save state label on %s", path);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -6372,7 +6335,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
|
|||||||
VIR_DOMAIN_XML_INACTIVE)))
|
VIR_DOMAIN_XML_INACTIVE)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virSecurityDriverVerify(def) < 0)
|
if (virSecurityManagerVerify(driver->securityManager, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
|
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
|
||||||
|
@ -83,10 +83,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
|
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
|
||||||
@ -115,10 +113,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, origdisk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, origdisk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
|
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
|
||||||
|
|
||||||
VIR_FREE(origdisk->src);
|
VIR_FREE(origdisk->src);
|
||||||
@ -134,10 +130,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
VIR_FREE(driveAlias);
|
VIR_FREE(driveAlias);
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on new media %s", disk->src);
|
VIR_WARN("Unable to restore security label on new media %s", disk->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -162,10 +156,8 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
@ -232,10 +224,8 @@ error:
|
|||||||
qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
|
qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on %s", disk->src);
|
VIR_WARN("Unable to release PCI address on %s", disk->src);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on %s", disk->src);
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -375,10 +365,8 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* We should have an address already, so make sure */
|
/* We should have an address already, so make sure */
|
||||||
@ -464,10 +452,8 @@ error:
|
|||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on %s", disk->src);
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -492,10 +478,8 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!disk->src) {
|
if (!disk->src) {
|
||||||
@ -551,10 +535,8 @@ error:
|
|||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on %s", disk->src);
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -979,10 +961,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainSetSecurityHostdevLabel &&
|
vm, hostdev) < 0)
|
||||||
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
|
|
||||||
vm, hostdev) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
switch (hostdev->source.subsys.type) {
|
switch (hostdev->source.subsys.type) {
|
||||||
@ -1008,10 +988,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel &&
|
vm, hostdev) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
|
|
||||||
vm, hostdev) < 0)
|
|
||||||
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
|
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -1183,10 +1161,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
|
|||||||
|
|
||||||
virDomainDiskDefFree(detach);
|
virDomainDiskDefFree(detach);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, dev->data.disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, dev->data.disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
||||||
|
|
||||||
if (cgroup != NULL) {
|
if (cgroup != NULL) {
|
||||||
@ -1263,10 +1239,8 @@ int qemuDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
|
|||||||
|
|
||||||
virDomainDiskDefFree(detach);
|
virDomainDiskDefFree(detach);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
vm, dev->data.disk) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
|
|
||||||
vm, dev->data.disk) < 0)
|
|
||||||
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
||||||
|
|
||||||
if (cgroup != NULL) {
|
if (cgroup != NULL) {
|
||||||
@ -1699,10 +1673,8 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel &&
|
vm, dev->data.hostdev) < 0)
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
|
|
||||||
vm, dev->data.hostdev) < 0)
|
|
||||||
VIR_WARN0("Failed to restore host device labelling");
|
VIR_WARN0("Failed to restore host device labelling");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,576 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* QEMU POSIX DAC security driver
|
|
||||||
*/
|
|
||||||
#include <config.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "qemu_security_dac.h"
|
|
||||||
#include "qemu_conf.h"
|
|
||||||
#include "datatypes.h"
|
|
||||||
#include "virterror_internal.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "logging.h"
|
|
||||||
#include "pci.h"
|
|
||||||
#include "hostusb.h"
|
|
||||||
#include "storage_file.h"
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
|
||||||
|
|
||||||
static struct qemud_driver *driver;
|
|
||||||
|
|
||||||
void qemuSecurityDACSetDriver(struct qemud_driver *newdriver)
|
|
||||||
{
|
|
||||||
driver = newdriver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetOwnership(const char *path, int uid, int gid)
|
|
||||||
{
|
|
||||||
VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
|
|
||||||
|
|
||||||
if (chown(path, uid, gid) < 0) {
|
|
||||||
struct stat sb;
|
|
||||||
int chown_errno = errno;
|
|
||||||
|
|
||||||
if (stat(path, &sb) >= 0) {
|
|
||||||
if (sb.st_uid == uid &&
|
|
||||||
sb.st_gid == gid) {
|
|
||||||
/* It's alright, there's nothing to change anyway. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chown_errno == EOPNOTSUPP) {
|
|
||||||
VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
|
|
||||||
uid, gid, path);
|
|
||||||
} else if (chown_errno == EPERM) {
|
|
||||||
VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
|
|
||||||
uid, gid, path);
|
|
||||||
} else if (chown_errno == EROFS) {
|
|
||||||
VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
|
|
||||||
uid, gid, path);
|
|
||||||
} else {
|
|
||||||
virReportSystemError(chown_errno,
|
|
||||||
_("unable to set user and group to '%d:%d' on '%s'"),
|
|
||||||
uid, gid, path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityFileLabel(const char *path)
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
int rc = -1;
|
|
||||||
char *newpath = NULL;
|
|
||||||
|
|
||||||
VIR_INFO("Restoring DAC user and group on '%s'", path);
|
|
||||||
|
|
||||||
if (virFileResolveLink(path, &newpath) < 0) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot resolve symlink %s"), path);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(newpath, &buf) != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* XXX record previous ownership */
|
|
||||||
rc = qemuSecurityDACSetOwnership(newpath, 0, 0);
|
|
||||||
|
|
||||||
err:
|
|
||||||
VIR_FREE(newpath);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
|
|
||||||
const char *path,
|
|
||||||
size_t depth ATTRIBUTE_UNUSED,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
|
||||||
virDomainDiskDefPtr disk)
|
|
||||||
|
|
||||||
{
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return virDomainDiskDefForeachPath(disk,
|
|
||||||
driver->allowDiskFormatProbing,
|
|
||||||
false,
|
|
||||||
qemuSecurityDACSetSecurityFileLabel,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
|
||||||
virDomainDiskDefPtr disk,
|
|
||||||
int migrated)
|
|
||||||
{
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Don't restore labels on readoly/shared disks, because
|
|
||||||
* other VMs may still be accessing these
|
|
||||||
* Alternatively we could iterate over all running
|
|
||||||
* domains and try to figure out if it is in use, but
|
|
||||||
* this would not work for clustered filesystems, since
|
|
||||||
* we can't see running VMs using the file on other nodes
|
|
||||||
* Safest bet is thus to skip the restore step.
|
|
||||||
*/
|
|
||||||
if (disk->readonly || disk->shared)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* If we have a shared FS & doing migrated, we must not
|
|
||||||
* change ownership, because that kills access on the
|
|
||||||
* destination host which is sub-optimal for the guest
|
|
||||||
* VM's I/O attempts :-)
|
|
||||||
*/
|
|
||||||
if (migrated) {
|
|
||||||
int rc = virStorageFileIsSharedFS(disk->src);
|
|
||||||
if (rc < 0)
|
|
||||||
return -1;
|
|
||||||
if (rc == 1) {
|
|
||||||
VIR_DEBUG("Skipping image label restore on %s because FS is shared",
|
|
||||||
disk->src);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return qemuSecurityDACRestoreSecurityFileLabel(disk->src);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainDiskDefPtr disk)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|
||||||
const char *file,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|
||||||
const char *file,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainHostdevDefPtr dev)
|
|
||||||
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (dev->source.subsys.type) {
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
|
||||||
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
|
||||||
dev->source.subsys.u.usb.device);
|
|
||||||
|
|
||||||
if (!usb)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
ret = usbDeviceFileIterate(usb, qemuSecurityDACSetSecurityUSBLabel, vm);
|
|
||||||
usbFreeDevice(usb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
|
||||||
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
|
||||||
dev->source.subsys.u.pci.bus,
|
|
||||||
dev->source.subsys.u.pci.slot,
|
|
||||||
dev->source.subsys.u.pci.function);
|
|
||||||
|
|
||||||
if (!pci)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
ret = pciDeviceFileIterate(pci, qemuSecurityDACSetSecurityPCILabel, vm);
|
|
||||||
pciFreeDevice(pci);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|
||||||
const char *file,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACRestoreSecurityFileLabel(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|
||||||
const char *file,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
return qemuSecurityDACRestoreSecurityFileLabel(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
|
||||||
virDomainHostdevDefPtr dev)
|
|
||||||
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (dev->source.subsys.type) {
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
|
||||||
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
|
||||||
dev->source.subsys.u.usb.device);
|
|
||||||
|
|
||||||
if (!usb)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
ret = usbDeviceFileIterate(usb, qemuSecurityDACRestoreSecurityUSBLabel, NULL);
|
|
||||||
usbFreeDevice(usb);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
|
||||||
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
|
||||||
dev->source.subsys.u.pci.bus,
|
|
||||||
dev->source.subsys.u.pci.slot,
|
|
||||||
dev->source.subsys.u.pci.function);
|
|
||||||
|
|
||||||
if (!pci)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
ret = pciDeviceFileIterate(pci, qemuSecurityDACRestoreSecurityPCILabel, NULL);
|
|
||||||
pciFreeDevice(pci);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetChardevLabel(virDomainObjPtr vm,
|
|
||||||
virDomainChrDefPtr dev)
|
|
||||||
|
|
||||||
{
|
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
|
||||||
char *in = NULL, *out = NULL;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (dev->type) {
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
|
||||||
ret = qemuSecurityDACSetOwnership(dev->data.file.path, driver->user, driver->group);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
|
||||||
if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
|
|
||||||
(virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
|
|
||||||
virReportOOMError();
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((qemuSecurityDACSetOwnership(in, driver->user, driver->group) < 0) ||
|
|
||||||
(qemuSecurityDACSetOwnership(out, driver->user, driver->group) < 0))
|
|
||||||
goto done;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
VIR_FREE(in);
|
|
||||||
VIR_FREE(out);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreChardevLabel(virDomainObjPtr vm,
|
|
||||||
virDomainChrDefPtr dev)
|
|
||||||
|
|
||||||
{
|
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
|
||||||
char *in = NULL, *out = NULL;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (dev->type) {
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
|
||||||
ret = qemuSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
|
||||||
if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
|
|
||||||
(virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
|
|
||||||
virReportOOMError();
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((qemuSecurityDACRestoreSecurityFileLabel(out) < 0) ||
|
|
||||||
(qemuSecurityDACRestoreSecurityFileLabel(in) < 0))
|
|
||||||
goto done;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
VIR_FREE(in);
|
|
||||||
VIR_FREE(out);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
||||||
virDomainChrDefPtr dev,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virDomainObjPtr vm = opaque;
|
|
||||||
|
|
||||||
return qemuSecurityDACRestoreChardevLabel(vm, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
int migrated)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
VIR_DEBUG("Restoring security label on %s migrated=%d",
|
|
||||||
vm->def->name, migrated);
|
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
|
||||||
if (qemuSecurityDACRestoreSecurityHostdevLabel(drv,
|
|
||||||
vm,
|
|
||||||
vm->def->hostdevs[i]) < 0)
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
||||||
if (qemuSecurityDACRestoreSecurityImageLabelInt(drv,
|
|
||||||
vm,
|
|
||||||
vm->def->disks[i],
|
|
||||||
migrated) < 0)
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virDomainChrDefForeach(vm->def,
|
|
||||||
false,
|
|
||||||
qemuSecurityDACRestoreChardevCallback,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (vm->def->os.kernel &&
|
|
||||||
qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (vm->def->os.initrd &&
|
|
||||||
qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
||||||
virDomainChrDefPtr dev,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virDomainObjPtr vm = opaque;
|
|
||||||
|
|
||||||
return qemuSecurityDACSetChardevLabel(vm, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
const char *stdin_path ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
||||||
/* XXX fixme - we need to recursively label the entriy tree :-( */
|
|
||||||
if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
|
|
||||||
continue;
|
|
||||||
if (qemuSecurityDACSetSecurityImageLabel(drv,
|
|
||||||
vm,
|
|
||||||
vm->def->disks[i]) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
|
||||||
if (qemuSecurityDACSetSecurityHostdevLabel(drv,
|
|
||||||
vm,
|
|
||||||
vm->def->hostdevs[i]) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virDomainChrDefForeach(vm->def,
|
|
||||||
true,
|
|
||||||
qemuSecurityDACSetChardevCallback,
|
|
||||||
vm) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (vm->def->os.kernel &&
|
|
||||||
qemuSecurityDACSetOwnership(vm->def->os.kernel,
|
|
||||||
driver->user,
|
|
||||||
driver->group) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (vm->def->os.initrd &&
|
|
||||||
qemuSecurityDACSetOwnership(vm->def->os.initrd,
|
|
||||||
driver->user,
|
|
||||||
driver->group) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
|
||||||
const char *savefile)
|
|
||||||
{
|
|
||||||
if (!driver->privileged)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return qemuSecurityDACSetOwnership(savefile, driver->user, driver->group);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
|
||||||
const char *savefile)
|
|
||||||
{
|
|
||||||
if (!driver->privileged || !driver->dynamicOwnership)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return qemuSecurityDACRestoreSecurityFileLabel(savefile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityDACSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
DEBUG("Dropping privileges of VM to %d:%d", driver->user, driver->group);
|
|
||||||
|
|
||||||
if (!driver->privileged)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (virSetUIDGID(driver->user, driver->group) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virSecurityDriver qemuDACSecurityDriver = {
|
|
||||||
.name = "qemuDAC",
|
|
||||||
|
|
||||||
.domainSetSecurityProcessLabel = qemuSecurityDACSetProcessLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityImageLabel = qemuSecurityDACSetSecurityImageLabel,
|
|
||||||
.domainRestoreSecurityImageLabel = qemuSecurityDACRestoreSecurityImageLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityAllLabel = qemuSecurityDACSetSecurityAllLabel,
|
|
||||||
.domainRestoreSecurityAllLabel = qemuSecurityDACRestoreSecurityAllLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityHostdevLabel = qemuSecurityDACSetSecurityHostdevLabel,
|
|
||||||
.domainRestoreSecurityHostdevLabel = qemuSecurityDACRestoreSecurityHostdevLabel,
|
|
||||||
|
|
||||||
.domainSetSavedStateLabel = qemuSecurityDACSetSavedStateLabel,
|
|
||||||
.domainRestoreSavedStateLabel = qemuSecurityDACRestoreSavedStateLabel,
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* QEMU POSIX DAC security driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "security/security_driver.h"
|
|
||||||
#include "qemu_conf.h"
|
|
||||||
|
|
||||||
#ifndef __QEMU_SECURITY_DAC
|
|
||||||
# define __QEMU_SECURITY_DAC
|
|
||||||
|
|
||||||
extern virSecurityDriver qemuDACSecurityDriver;
|
|
||||||
|
|
||||||
void qemuSecurityDACSetDriver(struct qemud_driver *driver);
|
|
||||||
|
|
||||||
#endif /* __QEMU_SECURITY_DAC */
|
|
@ -1,418 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* QEMU stacked security driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "qemu_security_stacked.h"
|
|
||||||
|
|
||||||
#include "qemu_conf.h"
|
|
||||||
#include "datatypes.h"
|
|
||||||
#include "virterror_internal.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "logging.h"
|
|
||||||
#include "pci.h"
|
|
||||||
#include "hostusb.h"
|
|
||||||
#include "storage_file.h"
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
|
||||||
|
|
||||||
|
|
||||||
static struct qemud_driver *driver;
|
|
||||||
|
|
||||||
void qemuSecurityStackedSetDriver(struct qemud_driver *newdriver)
|
|
||||||
{
|
|
||||||
driver = newdriver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedVerify(virDomainDefPtr def)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSecurityVerify &&
|
|
||||||
driver->securitySecondaryDriver->domainSecurityVerify(def) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSecurityVerify &&
|
|
||||||
driver->securityPrimaryDriver->domainSecurityVerify(def) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainGenSecurityLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainGenSecurityLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainReleaseSecurityLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainReleaseSecurityLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainReserveSecurityLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainReserveSecurityLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainDiskDefPtr disk)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityImageLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityImageLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainDiskDefPtr disk)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityImageLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityImageLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, disk) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainHostdevDefPtr dev)
|
|
||||||
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityHostdevLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, dev) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityHostdevLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, dev) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virDomainHostdevDefPtr dev)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, dev) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, dev) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
const char *stdin_path)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityAllLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, stdin_path) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityAllLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, stdin_path) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
int migrated)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, migrated) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, migrated) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
const char *savefile)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSavedStateLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, savefile) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSavedStateLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, savefile) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
const char *savefile)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSavedStateLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver,
|
|
||||||
vm, savefile) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSavedStateLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver,
|
|
||||||
vm, savefile) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityProcessLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecurityProcessLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityProcessLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecurityProcessLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm,
|
|
||||||
virSecurityLabelPtr seclabel)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainGetSecurityProcessLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver,
|
|
||||||
vm,
|
|
||||||
seclabel) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedSetSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecuritySocketLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainSetSecuritySocketLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecuritySocketLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainSetSecuritySocketLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSecurityStackedClearSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (driver->securitySecondaryDriver &&
|
|
||||||
driver->securitySecondaryDriver->domainClearSecuritySocketLabel &&
|
|
||||||
driver->securitySecondaryDriver->domainClearSecuritySocketLabel(driver->securitySecondaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
if (driver->securityPrimaryDriver &&
|
|
||||||
driver->securityPrimaryDriver->domainClearSecuritySocketLabel &&
|
|
||||||
driver->securityPrimaryDriver->domainClearSecuritySocketLabel(driver->securityPrimaryDriver,
|
|
||||||
vm) < 0)
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virSecurityDriver qemuStackedSecurityDriver = {
|
|
||||||
.name = "qemuStacked",
|
|
||||||
.domainSecurityVerify = qemuSecurityStackedVerify,
|
|
||||||
|
|
||||||
.domainGenSecurityLabel = qemuSecurityStackedGenLabel,
|
|
||||||
.domainReleaseSecurityLabel = qemuSecurityStackedReleaseLabel,
|
|
||||||
.domainReserveSecurityLabel = qemuSecurityStackedReserveLabel,
|
|
||||||
|
|
||||||
.domainGetSecurityProcessLabel = qemuSecurityStackedGetProcessLabel,
|
|
||||||
.domainSetSecurityProcessLabel = qemuSecurityStackedSetProcessLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityImageLabel = qemuSecurityStackedSetSecurityImageLabel,
|
|
||||||
.domainRestoreSecurityImageLabel = qemuSecurityStackedRestoreSecurityImageLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityAllLabel = qemuSecurityStackedSetSecurityAllLabel,
|
|
||||||
.domainRestoreSecurityAllLabel = qemuSecurityStackedRestoreSecurityAllLabel,
|
|
||||||
|
|
||||||
.domainSetSecurityHostdevLabel = qemuSecurityStackedSetSecurityHostdevLabel,
|
|
||||||
.domainRestoreSecurityHostdevLabel = qemuSecurityStackedRestoreSecurityHostdevLabel,
|
|
||||||
|
|
||||||
.domainSetSavedStateLabel = qemuSecurityStackedSetSavedStateLabel,
|
|
||||||
.domainRestoreSavedStateLabel = qemuSecurityStackedRestoreSavedStateLabel,
|
|
||||||
|
|
||||||
.domainClearSecuritySocketLabel = qemuSecurityStackedClearSocketLabel,
|
|
||||||
.domainSetSecuritySocketLabel = qemuSecurityStackedSetSocketLabel,
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* QEMU stacked security driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "security/security_driver.h"
|
|
||||||
#include "qemu_conf.h"
|
|
||||||
|
|
||||||
#ifndef __QEMU_SECURITY_STACKED
|
|
||||||
# define __QEMU_SECURITY_STACKED
|
|
||||||
|
|
||||||
extern virSecurityDriver qemuStackedSecurityDriver;
|
|
||||||
|
|
||||||
void qemuSecurityStackedSetDriver(struct qemud_driver *driver);
|
|
||||||
|
|
||||||
#endif /* __QEMU_SECURITY_DAC */
|
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* AppArmor security driver for libvirt
|
* AppArmor security driver for libvirt
|
||||||
* Copyright (C) 2009-2010 Canonical Ltd.
|
* Copyright (C) 2009-2010 Canonical Ltd.
|
||||||
@ -28,7 +27,6 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include "security_driver.h"
|
|
||||||
#include "security_apparmor.h"
|
#include "security_apparmor.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@ -47,7 +45,7 @@
|
|||||||
|
|
||||||
/* Data structure to pass to *FileIterate so we have everything we need */
|
/* Data structure to pass to *FileIterate so we have everything we need */
|
||||||
struct SDPDOP {
|
struct SDPDOP {
|
||||||
virSecurityDriverPtr drv;
|
virSecurityManagerPtr mgr;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,7 +156,7 @@ profile_status_file(const char *str)
|
|||||||
* load (add) a profile. Will create one if necessary
|
* load (add) a profile. Will create one if necessary
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
load_profile(virSecurityDriverPtr drv,
|
load_profile(virSecurityManagerPtr mgr,
|
||||||
const char *profile,
|
const char *profile,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *fn,
|
const char *fn,
|
||||||
@ -169,7 +167,7 @@ load_profile(virSecurityDriverPtr drv,
|
|||||||
char *xml = NULL;
|
char *xml = NULL;
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
pid_t child;
|
pid_t child;
|
||||||
const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
|
const char *probe = virSecurityManagerGetAllowDiskFormatProbing(mgr)
|
||||||
? "1" : "0";
|
? "1" : "0";
|
||||||
|
|
||||||
if (pipe(pipefd) < -1) {
|
if (pipe(pipefd) < -1) {
|
||||||
@ -300,7 +298,7 @@ cleanup:
|
|||||||
* NULL.
|
* NULL.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
reload_profile(virSecurityDriverPtr drv,
|
reload_profile(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *fn,
|
const char *fn,
|
||||||
bool append)
|
bool append)
|
||||||
@ -317,7 +315,7 @@ reload_profile(virSecurityDriverPtr drv,
|
|||||||
|
|
||||||
/* Update the profile only if it is loaded */
|
/* Update the profile only if it is loaded */
|
||||||
if (profile_loaded(secdef->imagelabel) >= 0) {
|
if (profile_loaded(secdef->imagelabel) >= 0) {
|
||||||
if (load_profile(drv, secdef->imagelabel, vm, fn, append) < 0) {
|
if (load_profile(mgr, secdef->imagelabel, vm, fn, append) < 0) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile "
|
||||||
"\'%s\'"),
|
"\'%s\'"),
|
||||||
@ -340,7 +338,7 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
struct SDPDOP *ptr = opaque;
|
struct SDPDOP *ptr = opaque;
|
||||||
virDomainObjPtr vm = ptr->vm;
|
virDomainObjPtr vm = ptr->vm;
|
||||||
|
|
||||||
if (reload_profile(ptr->drv, vm, file, true) < 0) {
|
if (reload_profile(ptr->mgr, vm, file, true) < 0) {
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile "
|
||||||
@ -358,7 +356,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
struct SDPDOP *ptr = opaque;
|
struct SDPDOP *ptr = opaque;
|
||||||
virDomainObjPtr vm = ptr->vm;
|
virDomainObjPtr vm = ptr->vm;
|
||||||
|
|
||||||
if (reload_profile(ptr->drv, vm, file, true) < 0) {
|
if (reload_profile(ptr->mgr, vm, file, true) < 0) {
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile "
|
||||||
@ -371,7 +369,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
/* Called on libvirtd startup to see if AppArmor is available */
|
/* Called on libvirtd startup to see if AppArmor is available */
|
||||||
static int
|
static int
|
||||||
AppArmorSecurityDriverProbe(void)
|
AppArmorSecurityManagerProbe(void)
|
||||||
{
|
{
|
||||||
char *template = NULL;
|
char *template = NULL;
|
||||||
int rc = SECURITY_DRIVER_DISABLE;
|
int rc = SECURITY_DRIVER_DISABLE;
|
||||||
@ -403,21 +401,37 @@ AppArmorSecurityDriverProbe(void)
|
|||||||
* currently not used.
|
* currently not used.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
|
AppArmorSecurityManagerOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
bool allowDiskFormatProbing)
|
|
||||||
{
|
{
|
||||||
virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
|
|
||||||
virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
AppArmorSecurityManagerClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
AppArmorSecurityManagerGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return SECURITY_APPARMOR_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
AppArmorSecurityManagerGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return SECURITY_APPARMOR_VOID_DOI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
|
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
|
||||||
* use a profile based on the UUID, otherwise create one based on a template.
|
* use a profile based on the UUID, otherwise create one based on a template.
|
||||||
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
|
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
|
||||||
* called on shutdown.
|
* called on shutdown.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
@ -472,7 +486,7 @@ AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
|
AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm, const char *stdin_path)
|
virDomainObjPtr vm, const char *stdin_path)
|
||||||
{
|
{
|
||||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
|
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||||
@ -480,7 +494,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
|
|||||||
|
|
||||||
/* if the profile is not already loaded, then load one */
|
/* if the profile is not already loaded, then load one */
|
||||||
if (profile_loaded(vm->def->seclabel.label) < 0) {
|
if (profile_loaded(vm->def->seclabel.label) < 0) {
|
||||||
if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path,
|
if (load_profile(mgr, vm->def->seclabel.label, vm, stdin_path,
|
||||||
false) < 0) {
|
false) < 0) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot generate AppArmor profile "
|
_("cannot generate AppArmor profile "
|
||||||
@ -496,7 +510,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
|
|||||||
* running.
|
* running.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
AppArmorGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virSecurityLabelPtr sec)
|
virSecurityLabelPtr sec)
|
||||||
{
|
{
|
||||||
@ -530,7 +544,7 @@ AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
* more details. Currently called via qemudShutdownVMDaemon.
|
* more details. Currently called via qemudShutdownVMDaemon.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
@ -544,7 +558,7 @@ AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
int migrated ATTRIBUTE_UNUSED)
|
int migrated ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -565,7 +579,7 @@ AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
|
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
|
AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
@ -574,12 +588,12 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
|
|||||||
if ((profile_name = get_profile_name(vm)) == NULL)
|
if ((profile_name = get_profile_name(vm)) == NULL)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (STRNEQ(drv->name, secdef->model)) {
|
if (STRNEQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
"\'%s\' model configured for domain, but "
|
"\'%s\' model configured for domain, but "
|
||||||
"hypervisor driver is \'%s\'."),
|
"hypervisor driver is \'%s\'."),
|
||||||
secdef->model, drv->name);
|
secdef->model, virSecurityManagerGetModel(mgr));
|
||||||
if (use_apparmor() > 0)
|
if (use_apparmor() > 0)
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
@ -597,19 +611,33 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
AppArmorSetSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
AppArmorClearSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Called when hotplugging */
|
/* Called when hotplugging */
|
||||||
static int
|
static int
|
||||||
AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv,
|
AppArmorRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
|
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
return reload_profile(drv, vm, NULL, false);
|
return reload_profile(mgr, vm, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when hotplugging */
|
/* Called when hotplugging */
|
||||||
static int
|
static int
|
||||||
AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
|
AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm, virDomainDiskDefPtr disk)
|
virDomainObjPtr vm, virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
@ -635,7 +663,7 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
|
|||||||
|
|
||||||
/* update the profile only if it is loaded */
|
/* update the profile only if it is loaded */
|
||||||
if (profile_loaded(secdef->imagelabel) >= 0) {
|
if (profile_loaded(secdef->imagelabel) >= 0) {
|
||||||
if (load_profile(drv, secdef->imagelabel, vm, disk->src,
|
if (load_profile(mgr, secdef->imagelabel, vm, disk->src,
|
||||||
false) < 0) {
|
false) < 0) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile "
|
||||||
@ -654,7 +682,8 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorSecurityVerify(virDomainDefPtr def)
|
AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
|
|
||||||
@ -670,7 +699,7 @@ AppArmorSecurityVerify(virDomainDefPtr def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
AppArmorReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* NOOP. Nothing to reserve with AppArmor */
|
/* NOOP. Nothing to reserve with AppArmor */
|
||||||
@ -678,7 +707,7 @@ AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
|
AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
@ -698,7 +727,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
|
|||||||
|
|
||||||
if (VIR_ALLOC(ptr) < 0)
|
if (VIR_ALLOC(ptr) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ptr->drv = drv;
|
ptr->mgr = mgr;
|
||||||
ptr->vm = vm;
|
ptr->vm = vm;
|
||||||
|
|
||||||
switch (dev->source.subsys.type) {
|
switch (dev->source.subsys.type) {
|
||||||
@ -740,7 +769,7 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
|
AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
||||||
|
|
||||||
@ -749,42 +778,57 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
|
|||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return reload_profile(drv, vm, NULL, false);
|
return reload_profile(mgr, vm, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorSetSavedStateLabel(virSecurityDriverPtr drv,
|
AppArmorSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
return reload_profile(drv, vm, savefile, true);
|
return reload_profile(mgr, vm, savefile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv,
|
AppArmorRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile ATTRIBUTE_UNUSED)
|
const char *savefile ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
return reload_profile(drv, vm, NULL, false);
|
return reload_profile(mgr, vm, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
virSecurityDriver virAppArmorSecurityDriver = {
|
virSecurityDriver virAppArmorSecurityDriver = {
|
||||||
.name = SECURITY_APPARMOR_NAME,
|
0,
|
||||||
.probe = AppArmorSecurityDriverProbe,
|
SECURITY_APPARMOR_NAME,
|
||||||
.open = AppArmorSecurityDriverOpen,
|
AppArmorSecurityManagerProbe,
|
||||||
.domainSecurityVerify = AppArmorSecurityVerify,
|
AppArmorSecurityManagerOpen,
|
||||||
.domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
|
AppArmorSecurityManagerClose,
|
||||||
.domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
|
|
||||||
.domainGenSecurityLabel = AppArmorGenSecurityLabel,
|
AppArmorSecurityManagerGetModel,
|
||||||
.domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
|
AppArmorSecurityManagerGetDOI,
|
||||||
.domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
|
|
||||||
.domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
|
AppArmorSecurityVerify,
|
||||||
.domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
|
|
||||||
.domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
|
AppArmorSetSecurityImageLabel,
|
||||||
.domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
|
AppArmorRestoreSecurityImageLabel,
|
||||||
.domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
|
|
||||||
.domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
|
AppArmorSetSecuritySocketLabel,
|
||||||
.domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
|
AppArmorClearSecuritySocketLabel,
|
||||||
.domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
|
|
||||||
|
AppArmorGenSecurityLabel,
|
||||||
|
AppArmorReserveSecurityLabel,
|
||||||
|
AppArmorReleaseSecurityLabel,
|
||||||
|
|
||||||
|
AppArmorGetSecurityProcessLabel,
|
||||||
|
AppArmorSetSecurityProcessLabel,
|
||||||
|
|
||||||
|
AppArmorSetSecurityAllLabel,
|
||||||
|
AppArmorRestoreSecurityAllLabel,
|
||||||
|
|
||||||
|
AppArmorSetSecurityHostdevLabel,
|
||||||
|
AppArmorRestoreSecurityHostdevLabel,
|
||||||
|
|
||||||
|
AppArmorSetSavedStateLabel,
|
||||||
|
AppArmorRestoreSavedStateLabel,
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#ifndef __VIR_SECURITY_APPARMOR_H__
|
#ifndef __VIR_SECURITY_APPARMOR_H__
|
||||||
# define __VIR_SECURITY_APPARMOR_H__
|
# define __VIR_SECURITY_APPARMOR_H__
|
||||||
|
|
||||||
|
# include "security_driver.h"
|
||||||
|
|
||||||
extern virSecurityDriver virAppArmorSecurityDriver;
|
extern virSecurityDriver virAppArmorSecurityDriver;
|
||||||
|
|
||||||
# define AA_PREFIX "libvirt-"
|
# define AA_PREFIX "libvirt-"
|
||||||
|
713
src/security/security_dac.c
Normal file
713
src/security/security_dac.c
Normal file
@ -0,0 +1,713 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* POSIX DAC security driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "security_dac.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "pci.h"
|
||||||
|
#include "hostusb.h"
|
||||||
|
#include "storage_file.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
||||||
|
|
||||||
|
typedef struct _virSecurityDACData virSecurityDACData;
|
||||||
|
typedef virSecurityDACData *virSecurityDACDataPtr;
|
||||||
|
|
||||||
|
struct _virSecurityDACData {
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
bool dynamicOwnership;
|
||||||
|
};
|
||||||
|
|
||||||
|
void virSecurityDACSetUser(virSecurityManagerPtr mgr,
|
||||||
|
uid_t user)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
priv->user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
|
||||||
|
gid_t group)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
priv->group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
|
||||||
|
bool dynamicOwnership)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
priv->dynamicOwnership = dynamicOwnership;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virSecurityDriverStatus
|
||||||
|
virSecurityDACProbe(void)
|
||||||
|
{
|
||||||
|
return SECURITY_DRIVER_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return "dac";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetOwnership(const char *path, int uid, int gid)
|
||||||
|
{
|
||||||
|
VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
|
||||||
|
|
||||||
|
if (chown(path, uid, gid) < 0) {
|
||||||
|
struct stat sb;
|
||||||
|
int chown_errno = errno;
|
||||||
|
|
||||||
|
if (stat(path, &sb) >= 0) {
|
||||||
|
if (sb.st_uid == uid &&
|
||||||
|
sb.st_gid == gid) {
|
||||||
|
/* It's alright, there's nothing to change anyway. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chown_errno == EOPNOTSUPP) {
|
||||||
|
VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
|
||||||
|
uid, gid, path);
|
||||||
|
} else if (chown_errno == EPERM) {
|
||||||
|
VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
|
||||||
|
uid, gid, path);
|
||||||
|
} else if (chown_errno == EROFS) {
|
||||||
|
VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
|
||||||
|
uid, gid, path);
|
||||||
|
} else {
|
||||||
|
virReportSystemError(chown_errno,
|
||||||
|
_("unable to set user and group to '%d:%d' on '%s'"),
|
||||||
|
uid, gid, path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityFileLabel(const char *path)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
int rc = -1;
|
||||||
|
char *newpath = NULL;
|
||||||
|
|
||||||
|
VIR_INFO("Restoring DAC user and group on '%s'", path);
|
||||||
|
|
||||||
|
if (virFileResolveLink(path, &newpath) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot resolve symlink %s"), path);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(newpath, &buf) != 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* XXX record previous ownership */
|
||||||
|
rc = virSecurityDACSetOwnership(newpath, 0, 0);
|
||||||
|
|
||||||
|
err:
|
||||||
|
VIR_FREE(newpath);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
|
||||||
|
const char *path,
|
||||||
|
size_t depth ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(path, priv->user, priv->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return virDomainDiskDefForeachPath(disk,
|
||||||
|
virSecurityManagerGetAllowDiskFormatProbing(mgr),
|
||||||
|
false,
|
||||||
|
virSecurityDACSetSecurityFileLabel,
|
||||||
|
mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDiskDefPtr disk,
|
||||||
|
int migrated)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Don't restore labels on readoly/shared disks, because
|
||||||
|
* other VMs may still be accessing these
|
||||||
|
* Alternatively we could iterate over all running
|
||||||
|
* domains and try to figure out if it is in use, but
|
||||||
|
* this would not work for clustered filesystems, since
|
||||||
|
* we can't see running VMs using the file on other nodes
|
||||||
|
* Safest bet is thus to skip the restore step.
|
||||||
|
*/
|
||||||
|
if (disk->readonly || disk->shared)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!disk->src)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* If we have a shared FS & doing migrated, we must not
|
||||||
|
* change ownership, because that kills access on the
|
||||||
|
* destination host which is sub-optimal for the guest
|
||||||
|
* VM's I/O attempts :-)
|
||||||
|
*/
|
||||||
|
if (migrated) {
|
||||||
|
int rc = virStorageFileIsSharedFS(disk->src);
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
if (rc == 1) {
|
||||||
|
VIR_DEBUG("Skipping image label restore on %s because FS is shared",
|
||||||
|
disk->src);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return virSecurityDACRestoreSecurityFileLabel(disk->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
{
|
||||||
|
return virSecurityDACRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
const char *file,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(file, priv->user, priv->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
const char *file,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(file, priv->user, priv->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (dev->source.subsys.type) {
|
||||||
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||||
|
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
||||||
|
dev->source.subsys.u.usb.device);
|
||||||
|
|
||||||
|
if (!usb)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
|
||||||
|
usbFreeDevice(usb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
||||||
|
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
||||||
|
dev->source.subsys.u.pci.bus,
|
||||||
|
dev->source.subsys.u.pci.slot,
|
||||||
|
dev->source.subsys.u.pci.function);
|
||||||
|
|
||||||
|
if (!pci)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
|
||||||
|
pciFreeDevice(pci);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
const char *file,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virSecurityDACRestoreSecurityFileLabel(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
const char *file,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virSecurityDACRestoreSecurityFileLabel(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (dev->source.subsys.type) {
|
||||||
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||||
|
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
||||||
|
dev->source.subsys.u.usb.device);
|
||||||
|
|
||||||
|
if (!usb)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = usbDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
|
||||||
|
usbFreeDevice(usb);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
||||||
|
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
||||||
|
dev->source.subsys.u.pci.bus,
|
||||||
|
dev->source.subsys.u.pci.slot,
|
||||||
|
dev->source.subsys.u.pci.function);
|
||||||
|
|
||||||
|
if (!pci)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = pciDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
|
||||||
|
pciFreeDevice(pci);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainChrDefPtr dev)
|
||||||
|
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
char *in = NULL, *out = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
switch (dev->type) {
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||||
|
ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
||||||
|
if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
|
||||||
|
(virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
|
||||||
|
(virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
|
||||||
|
goto done;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
VIR_FREE(in);
|
||||||
|
VIR_FREE(out);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainChrDefPtr dev)
|
||||||
|
{
|
||||||
|
char *in = NULL, *out = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
switch (dev->type) {
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||||
|
ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
||||||
|
if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
|
||||||
|
(virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
|
||||||
|
(virSecurityDACRestoreSecurityFileLabel(in) < 0))
|
||||||
|
goto done;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
VIR_FREE(in);
|
||||||
|
VIR_FREE(out);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
|
virDomainChrDefPtr dev,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
|
return virSecurityDACRestoreChardevLabel(mgr, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
int migrated)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int i;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
VIR_DEBUG("Restoring security label on %s migrated=%d",
|
||||||
|
vm->def->name, migrated);
|
||||||
|
|
||||||
|
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
||||||
|
if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
|
||||||
|
vm,
|
||||||
|
vm->def->hostdevs[i]) < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
|
if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
|
||||||
|
vm,
|
||||||
|
vm->def->disks[i],
|
||||||
|
migrated) < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainChrDefForeach(vm->def,
|
||||||
|
false,
|
||||||
|
virSecurityDACRestoreChardevCallback,
|
||||||
|
vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
if (vm->def->os.kernel &&
|
||||||
|
virSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
if (vm->def->os.initrd &&
|
||||||
|
virSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
|
virDomainChrDefPtr dev,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
|
return virSecurityDACSetChardevLabel(mgr, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *stdin_path ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
|
/* XXX fixme - we need to recursively label the entire tree :-( */
|
||||||
|
if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
|
||||||
|
continue;
|
||||||
|
if (virSecurityDACSetSecurityImageLabel(mgr,
|
||||||
|
vm,
|
||||||
|
vm->def->disks[i]) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
||||||
|
if (virSecurityDACSetSecurityHostdevLabel(mgr,
|
||||||
|
vm,
|
||||||
|
vm->def->hostdevs[i]) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainChrDefForeach(vm->def,
|
||||||
|
true,
|
||||||
|
virSecurityDACSetChardevCallback,
|
||||||
|
vm) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (vm->def->os.kernel &&
|
||||||
|
virSecurityDACSetOwnership(vm->def->os.kernel,
|
||||||
|
priv->user,
|
||||||
|
priv->group) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (vm->def->os.initrd &&
|
||||||
|
virSecurityDACSetOwnership(vm->def->os.initrd,
|
||||||
|
priv->user,
|
||||||
|
priv->group) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
if (!priv->dynamicOwnership)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return virSecurityDACRestoreSecurityFileLabel(savefile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
DEBUG("Dropping privileges of VM to %d:%d", priv->user, priv->group);
|
||||||
|
|
||||||
|
if (virSetUIDGID(priv->user, priv->group) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virSecurityDriver virSecurityDriverDAC = {
|
||||||
|
sizeof(virSecurityDACData),
|
||||||
|
"virDAC",
|
||||||
|
|
||||||
|
virSecurityDACProbe,
|
||||||
|
virSecurityDACOpen,
|
||||||
|
virSecurityDACClose,
|
||||||
|
|
||||||
|
virSecurityDACGetModel,
|
||||||
|
virSecurityDACGetDOI,
|
||||||
|
|
||||||
|
virSecurityDACVerify,
|
||||||
|
|
||||||
|
virSecurityDACSetSecurityImageLabel,
|
||||||
|
virSecurityDACRestoreSecurityImageLabel,
|
||||||
|
|
||||||
|
virSecurityDACSetSocketLabel,
|
||||||
|
virSecurityDACClearSocketLabel,
|
||||||
|
|
||||||
|
virSecurityDACGenLabel,
|
||||||
|
virSecurityDACReserveLabel,
|
||||||
|
virSecurityDACReleaseLabel,
|
||||||
|
|
||||||
|
virSecurityDACGetProcessLabel,
|
||||||
|
virSecurityDACSetProcessLabel,
|
||||||
|
|
||||||
|
virSecurityDACSetSecurityAllLabel,
|
||||||
|
virSecurityDACRestoreSecurityAllLabel,
|
||||||
|
|
||||||
|
virSecurityDACSetSecurityHostdevLabel,
|
||||||
|
virSecurityDACRestoreSecurityHostdevLabel,
|
||||||
|
|
||||||
|
virSecurityDACSetSavedStateLabel,
|
||||||
|
virSecurityDACRestoreSavedStateLabel,
|
||||||
|
};
|
36
src/security/security_dac.h
Normal file
36
src/security/security_dac.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* POSIX DAC security driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "security_driver.h"
|
||||||
|
|
||||||
|
#ifndef __VIR_SECURITY_DAC
|
||||||
|
# define __VIR_SECURITY_DAC
|
||||||
|
|
||||||
|
extern virSecurityDriver virSecurityDriverDAC;
|
||||||
|
|
||||||
|
void virSecurityDACSetUser(virSecurityManagerPtr mgr,
|
||||||
|
uid_t user);
|
||||||
|
void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
|
||||||
|
gid_t group);
|
||||||
|
|
||||||
|
void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
|
||||||
|
bool dynamic);
|
||||||
|
|
||||||
|
#endif /* __VIR_SECURITY_DAC */
|
@ -14,6 +14,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#include "security_driver.h"
|
#include "security_driver.h"
|
||||||
#ifdef WITH_SECDRIVER_SELINUX
|
#ifdef WITH_SECDRIVER_SELINUX
|
||||||
@ -24,116 +25,53 @@
|
|||||||
# include "security_apparmor.h"
|
# include "security_apparmor.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "security_nop.h"
|
||||||
|
|
||||||
static virSecurityDriverPtr security_drivers[] = {
|
static virSecurityDriverPtr security_drivers[] = {
|
||||||
#ifdef WITH_SECDRIVER_SELINUX
|
#ifdef WITH_SECDRIVER_SELINUX
|
||||||
&virSELinuxSecurityDriver,
|
&virSecurityDriverSELinux,
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_SECDRIVER_APPARMOR
|
#ifdef WITH_SECDRIVER_APPARMOR
|
||||||
&virAppArmorSecurityDriver,
|
&virAppArmorSecurityDriver,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
&virSecurityDriverNop, /* Must always be last, since it will always probe */
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
virSecurityDriverPtr virSecurityDriverLookup(const char *name)
|
||||||
virSecurityDriverVerify(virDomainDefPtr def)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
virSecurityDriverPtr drv = NULL;
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
int i;
|
||||||
|
|
||||||
if (!secdef->model ||
|
VIR_DEBUG("name=%s", NULLSTR(name));
|
||||||
STREQ(secdef->model, "none"))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; security_drivers[i] != NULL ; i++) {
|
for (i = 0; i < ARRAY_CARDINALITY(security_drivers) && !drv ; i++) {
|
||||||
if (STREQ(security_drivers[i]->name, secdef->model)) {
|
|
||||||
return security_drivers[i]->domainSecurityVerify(def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virSecurityReportError(VIR_ERR_XML_ERROR,
|
|
||||||
_("invalid security model '%s'"), secdef->model);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
|
||||||
const char *name,
|
|
||||||
bool allowDiskFormatProbing)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (name && STREQ(name, "none"))
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
for (i = 0; security_drivers[i] != NULL ; i++) {
|
|
||||||
virSecurityDriverPtr tmp = security_drivers[i];
|
virSecurityDriverPtr tmp = security_drivers[i];
|
||||||
|
|
||||||
if (name && STRNEQ(tmp->name, name))
|
if (name &&
|
||||||
|
STRNEQ(tmp->name, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (tmp->probe()) {
|
switch (tmp->probe()) {
|
||||||
case SECURITY_DRIVER_ENABLE:
|
case SECURITY_DRIVER_ENABLE:
|
||||||
virSecurityDriverInit(tmp);
|
VIR_DEBUG("Probed name=%s", tmp->name);
|
||||||
if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
|
drv = tmp;
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
*drv = tmp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECURITY_DRIVER_DISABLE:
|
case SECURITY_DRIVER_DISABLE:
|
||||||
|
VIR_DEBUG("Not enabled name=%s", tmp->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if (!drv) {
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
virSecurityDriverInit(virSecurityDriverPtr drv)
|
|
||||||
{
|
|
||||||
memset(&drv->_private, 0, sizeof drv->_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
virSecurityDriverSetDOI(virSecurityDriverPtr drv,
|
|
||||||
const char *doi)
|
|
||||||
{
|
|
||||||
if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
|
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("%s: DOI \'%s\' is "
|
_("Security driver %s not found"),
|
||||||
"longer than the maximum allowed length of %d"),
|
NULLSTR(name));
|
||||||
__func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
|
return NULL;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
strcpy(drv->_private.doi, doi);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
return drv;
|
||||||
virSecurityDriverGetDOI(virSecurityDriverPtr drv)
|
|
||||||
{
|
|
||||||
return drv->_private.doi;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
virSecurityDriverGetModel(virSecurityDriverPtr drv)
|
|
||||||
{
|
|
||||||
return drv->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
|
|
||||||
bool allowDiskFormatProbing)
|
|
||||||
{
|
|
||||||
drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
|
|
||||||
{
|
|
||||||
return drv->_private.allowDiskFormatProbing;
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
# include "domain_conf.h"
|
# include "domain_conf.h"
|
||||||
|
|
||||||
|
# include "security_manager.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return values for security driver probing: the driver will determine
|
* Return values for security driver probing: the driver will determine
|
||||||
* whether it should be enabled or disabled.
|
* whether it should be enabled or disabled.
|
||||||
@ -29,104 +31,91 @@ typedef enum {
|
|||||||
typedef struct _virSecurityDriver virSecurityDriver;
|
typedef struct _virSecurityDriver virSecurityDriver;
|
||||||
typedef virSecurityDriver *virSecurityDriverPtr;
|
typedef virSecurityDriver *virSecurityDriverPtr;
|
||||||
|
|
||||||
typedef struct _virSecurityDriverState virSecurityDriverState;
|
|
||||||
typedef virSecurityDriverState *virSecurityDriverStatePtr;
|
|
||||||
|
|
||||||
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
|
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
|
||||||
typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDriverOpen) (virSecurityManagerPtr mgr);
|
||||||
bool allowDiskFormatProbing);
|
typedef int (*virSecurityDriverClose) (virSecurityManagerPtr mgr);
|
||||||
typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
|
|
||||||
|
typedef const char *(*virSecurityDriverGetModel) (virSecurityManagerPtr mgr);
|
||||||
|
typedef const char *(*virSecurityDriverGetDOI) (virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
|
typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk);
|
||||||
typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetSocketLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm);
|
virDomainObjPtr vm);
|
||||||
typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainClearSocketLabel)(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm);
|
virDomainObjPtr vm);
|
||||||
typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetImageLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk);
|
||||||
typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev);
|
virDomainHostdevDefPtr dev);
|
||||||
typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev);
|
virDomainHostdevDefPtr dev);
|
||||||
typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile);
|
const char *savefile);
|
||||||
typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile);
|
const char *savefile);
|
||||||
typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainGenLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr sec);
|
virDomainObjPtr sec);
|
||||||
typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainReserveLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr sec);
|
virDomainObjPtr sec);
|
||||||
typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr sec);
|
virDomainObjPtr sec);
|
||||||
typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr sec,
|
virDomainObjPtr sec,
|
||||||
const char *stdin_path);
|
const char *stdin_path);
|
||||||
typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
int migrated);
|
int migrated);
|
||||||
typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virSecurityLabelPtr sec);
|
virSecurityLabelPtr sec);
|
||||||
typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
|
typedef int (*virSecurityDomainSetProcessLabel) (virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm);
|
virDomainObjPtr vm);
|
||||||
typedef int (*virSecurityDomainSecurityVerify) (virDomainDefPtr def);
|
typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def);
|
||||||
|
|
||||||
|
|
||||||
struct _virSecurityDriver {
|
struct _virSecurityDriver {
|
||||||
|
size_t privateDataLen;
|
||||||
const char *name;
|
const char *name;
|
||||||
virSecurityDriverProbe probe;
|
virSecurityDriverProbe probe;
|
||||||
virSecurityDriverOpen open;
|
virSecurityDriverOpen open;
|
||||||
|
virSecurityDriverClose close;
|
||||||
|
|
||||||
|
virSecurityDriverGetModel getModel;
|
||||||
|
virSecurityDriverGetDOI getDOI;
|
||||||
|
|
||||||
virSecurityDomainSecurityVerify domainSecurityVerify;
|
virSecurityDomainSecurityVerify domainSecurityVerify;
|
||||||
|
|
||||||
|
virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
|
||||||
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
|
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
|
||||||
|
|
||||||
virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
|
virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
|
||||||
virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
|
virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
|
||||||
virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
|
|
||||||
virSecurityDomainGenLabel domainGenSecurityLabel;
|
virSecurityDomainGenLabel domainGenSecurityLabel;
|
||||||
virSecurityDomainReserveLabel domainReserveSecurityLabel;
|
virSecurityDomainReserveLabel domainReserveSecurityLabel;
|
||||||
virSecurityDomainReleaseLabel domainReleaseSecurityLabel;
|
virSecurityDomainReleaseLabel domainReleaseSecurityLabel;
|
||||||
|
|
||||||
virSecurityDomainGetProcessLabel domainGetSecurityProcessLabel;
|
virSecurityDomainGetProcessLabel domainGetSecurityProcessLabel;
|
||||||
virSecurityDomainSetProcessLabel domainSetSecurityProcessLabel;
|
virSecurityDomainSetProcessLabel domainSetSecurityProcessLabel;
|
||||||
|
|
||||||
virSecurityDomainSetAllLabel domainSetSecurityAllLabel;
|
virSecurityDomainSetAllLabel domainSetSecurityAllLabel;
|
||||||
virSecurityDomainRestoreAllLabel domainRestoreSecurityAllLabel;
|
virSecurityDomainRestoreAllLabel domainRestoreSecurityAllLabel;
|
||||||
virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
|
|
||||||
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
|
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
|
||||||
|
virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
|
||||||
|
|
||||||
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
|
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
|
||||||
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
||||||
|
|
||||||
/*
|
|
||||||
* This is internally managed driver state and should only be accessed
|
|
||||||
* via helpers below.
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
char doi[VIR_SECURITY_DOI_BUFLEN];
|
|
||||||
bool allowDiskFormatProbing;
|
|
||||||
} _private;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global methods */
|
virSecurityDriverPtr virSecurityDriverLookup(const char *name);
|
||||||
int virSecurityDriverStartup(virSecurityDriverPtr *drv,
|
|
||||||
const char *name,
|
|
||||||
bool allowDiskFormatProbing);
|
|
||||||
|
|
||||||
int
|
|
||||||
virSecurityDriverVerify(virDomainDefPtr def);
|
|
||||||
|
|
||||||
# define virSecurityReportError(code, ...) \
|
|
||||||
virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
|
|
||||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
/* Helpers */
|
|
||||||
void virSecurityDriverInit(virSecurityDriverPtr drv);
|
|
||||||
int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
|
|
||||||
const char *doi);
|
|
||||||
void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
|
|
||||||
bool allowDiskFormatProbing);
|
|
||||||
const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
|
|
||||||
const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
|
|
||||||
bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
|
|
||||||
|
|
||||||
#endif /* __VIR_SECURITY_H__ */
|
#endif /* __VIR_SECURITY_H__ */
|
||||||
|
317
src/security/security_manager.c
Normal file
317
src/security/security_manager.c
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
/*
|
||||||
|
* security_manager.c: Internal security manager API
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "security_driver.h"
|
||||||
|
#include "security_stack.h"
|
||||||
|
#include "security_dac.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
||||||
|
|
||||||
|
|
||||||
|
struct _virSecurityManager {
|
||||||
|
virSecurityDriverPtr drv;
|
||||||
|
bool allowDiskFormatProbing;
|
||||||
|
};
|
||||||
|
|
||||||
|
static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
|
||||||
|
bool allowDiskFormatProbing)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr;
|
||||||
|
|
||||||
|
if (VIR_ALLOC_VAR(mgr, char, drv->privateDataLen) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr->drv = drv;
|
||||||
|
mgr->allowDiskFormatProbing = allowDiskFormatProbing;
|
||||||
|
|
||||||
|
if (drv->open(mgr) < 0) {
|
||||||
|
virSecurityManagerFree(mgr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
|
||||||
|
virSecurityManagerPtr secondary)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr =
|
||||||
|
virSecurityManagerNewDriver(&virSecurityDriverStack,
|
||||||
|
virSecurityManagerGetAllowDiskFormatProbing(primary));
|
||||||
|
|
||||||
|
if (!mgr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
virSecurityStackSetPrimary(mgr, primary);
|
||||||
|
virSecurityStackSetSecondary(mgr, secondary);
|
||||||
|
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
|
||||||
|
gid_t group,
|
||||||
|
bool allowDiskFormatProbing,
|
||||||
|
bool dynamicOwnership)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr mgr =
|
||||||
|
virSecurityManagerNewDriver(&virSecurityDriverDAC,
|
||||||
|
allowDiskFormatProbing);
|
||||||
|
|
||||||
|
if (!mgr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
virSecurityDACSetUser(mgr, user);
|
||||||
|
virSecurityDACSetGroup(mgr, group);
|
||||||
|
virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);
|
||||||
|
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNew(const char *name,
|
||||||
|
bool allowDiskFormatProbing)
|
||||||
|
{
|
||||||
|
virSecurityDriverPtr drv = virSecurityDriverLookup(name);
|
||||||
|
if (!drv)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return virSecurityManagerNewDriver(drv, allowDiskFormatProbing);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
return ((char*)mgr) + sizeof(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virSecurityManagerFree(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
if (!mgr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mgr->drv->close)
|
||||||
|
mgr->drv->close(mgr);
|
||||||
|
|
||||||
|
VIR_FREE(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
if (mgr->drv->getDOI)
|
||||||
|
return mgr->drv->getDOI(mgr);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
virSecurityManagerGetModel(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
if (mgr->drv->getModel)
|
||||||
|
return mgr->drv->getModel(mgr);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
return mgr->allowDiskFormatProbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainRestoreSecurityImageLabel)
|
||||||
|
return mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, disk);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecuritySocketLabel)
|
||||||
|
return mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainClearSecuritySocketLabel)
|
||||||
|
return mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecurityImageLabel)
|
||||||
|
return mgr->drv->domainSetSecurityImageLabel(mgr, vm, disk);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainRestoreSecurityHostdevLabel)
|
||||||
|
return mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecurityHostdevLabel)
|
||||||
|
return mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSavedStateLabel)
|
||||||
|
return mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainRestoreSavedStateLabel)
|
||||||
|
return mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainGenSecurityLabel)
|
||||||
|
return mgr->drv->domainGenSecurityLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainReserveSecurityLabel)
|
||||||
|
return mgr->drv->domainReserveSecurityLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainReleaseSecurityLabel)
|
||||||
|
return mgr->drv->domainReleaseSecurityLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *stdin_path)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecurityAllLabel)
|
||||||
|
return mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
int migrated)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainRestoreSecurityAllLabel)
|
||||||
|
return mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virSecurityLabelPtr sec)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainGetSecurityProcessLabel)
|
||||||
|
return mgr->drv->domainGetSecurityProcessLabel(mgr, vm, sec);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSetSecurityProcessLabel)
|
||||||
|
return mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
if (mgr->drv->domainSecurityVerify)
|
||||||
|
return mgr->drv->domainSecurityVerify(mgr, def);
|
||||||
|
|
||||||
|
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
95
src/security/security_manager.h
Normal file
95
src/security/security_manager.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* security_manager.h: Internal security manager API
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VIR_SECURITY_MANAGER_H__
|
||||||
|
# define VIR_SECURITY_MANAGER_H__
|
||||||
|
|
||||||
|
# define virSecurityReportError(code, ...) \
|
||||||
|
virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
|
||||||
|
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _virSecurityManager virSecurityManager;
|
||||||
|
typedef virSecurityManager *virSecurityManagerPtr;
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNew(const char *name,
|
||||||
|
bool allowDiskFormatProbing);
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
|
||||||
|
virSecurityManagerPtr secondary);
|
||||||
|
|
||||||
|
virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
|
||||||
|
gid_t group,
|
||||||
|
bool allowDiskFormatProbing,
|
||||||
|
bool dynamicOwnership);
|
||||||
|
|
||||||
|
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
|
void virSecurityManagerFree(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
|
const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr);
|
||||||
|
const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
|
||||||
|
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
|
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk);
|
||||||
|
int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm);
|
||||||
|
int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm);
|
||||||
|
int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk);
|
||||||
|
int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev);
|
||||||
|
int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev);
|
||||||
|
int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile);
|
||||||
|
int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile);
|
||||||
|
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr sec);
|
||||||
|
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr sec);
|
||||||
|
int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr sec);
|
||||||
|
int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr sec,
|
||||||
|
const char *stdin_path);
|
||||||
|
int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
int migrated);
|
||||||
|
int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virSecurityLabelPtr sec);
|
||||||
|
int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm);
|
||||||
|
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def);
|
||||||
|
|
||||||
|
#endif /* VIR_SECURITY_MANAGER_H__ */
|
185
src/security/security_nop.c
Normal file
185
src/security/security_nop.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "security_nop.h"
|
||||||
|
|
||||||
|
static virSecurityDriverStatus virSecurityDriverProbeNop(void)
|
||||||
|
{
|
||||||
|
return SECURITY_DRIVER_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDriverOpenNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDriverCloseNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * virSecurityDriverGetModelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * virSecurityDriverGetDOINop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainRestoreImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainClearSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainRestoreHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
const char *savefile ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int virSecurityDomainRestoreSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
const char *savefile ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainGenLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr sec ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainReserveLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr sec ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr sec ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr sec ATTRIBUTE_UNUSED,
|
||||||
|
const char *stdin_path ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
int migrated ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int virSecurityDomainGetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||||
|
virSecurityLabelPtr sec ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainSetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSecurityDomainVerifyNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityDriver virSecurityDriverNop = {
|
||||||
|
0,
|
||||||
|
"none",
|
||||||
|
virSecurityDriverProbeNop,
|
||||||
|
virSecurityDriverOpenNop,
|
||||||
|
virSecurityDriverCloseNop,
|
||||||
|
|
||||||
|
virSecurityDriverGetModelNop,
|
||||||
|
virSecurityDriverGetDOINop,
|
||||||
|
|
||||||
|
virSecurityDomainVerifyNop,
|
||||||
|
|
||||||
|
virSecurityDomainSetImageLabelNop,
|
||||||
|
virSecurityDomainRestoreImageLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainSetSocketLabelNop,
|
||||||
|
virSecurityDomainClearSocketLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainGenLabelNop,
|
||||||
|
virSecurityDomainReserveLabelNop,
|
||||||
|
virSecurityDomainReleaseLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainGetProcessLabelNop,
|
||||||
|
virSecurityDomainSetProcessLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainSetAllLabelNop,
|
||||||
|
virSecurityDomainRestoreAllLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainSetHostdevLabelNop,
|
||||||
|
virSecurityDomainRestoreHostdevLabelNop,
|
||||||
|
|
||||||
|
virSecurityDomainSetSavedStateLabelNop,
|
||||||
|
virSecurityDomainRestoreSavedStateLabelNop,
|
||||||
|
};
|
27
src/security/security_nop.h
Normal file
27
src/security/security_nop.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_SECURITY_NOP_H__
|
||||||
|
# define __VIR_SECURITY_NOP_H__
|
||||||
|
|
||||||
|
# include "security_driver.h"
|
||||||
|
|
||||||
|
extern virSecurityDriver virSecurityDriverNop;
|
||||||
|
|
||||||
|
#endif /* __VIR_SECURITY_NOP_H__ */
|
@ -160,7 +160,7 @@ SELinuxInitialize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
@ -225,7 +225,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
security_context_t pctx;
|
security_context_t pctx;
|
||||||
@ -270,20 +270,34 @@ SELinuxSecurityDriverProbe(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
|
SELinuxSecurityDriverOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
bool allowDiskFormatProbing)
|
{
|
||||||
|
return SELinuxInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSecurityDriverClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *SELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return SECURITY_SELINUX_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *SELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Where will the DOI come from? SELinux configuration, or qemu
|
* Where will the DOI come from? SELinux configuration, or qemu
|
||||||
* configuration? For the moment, we'll just set it to "0".
|
* configuration? For the moment, we'll just set it to "0".
|
||||||
*/
|
*/
|
||||||
virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
|
return SECURITY_SELINUX_VOID_DOI;
|
||||||
virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
|
|
||||||
return SELinuxInitialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virSecurityLabelPtr sec)
|
virSecurityLabelPtr sec)
|
||||||
{
|
{
|
||||||
@ -415,7 +429,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
int migrated)
|
int migrated)
|
||||||
@ -460,11 +474,11 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv,
|
SELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0);
|
return SELinuxRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -498,13 +512,13 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
|
SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
|
bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||||
return 0;
|
return 0;
|
||||||
@ -538,7 +552,7 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
@ -607,7 +621,7 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
@ -756,7 +770,7 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
int migrated ATTRIBUTE_UNUSED)
|
int migrated ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -770,13 +784,13 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
||||||
if (SELinuxRestoreSecurityHostdevLabel(drv,
|
if (SELinuxRestoreSecurityHostdevLabel(mgr,
|
||||||
vm,
|
vm,
|
||||||
vm->def->hostdevs[i]) < 0)
|
vm->def->hostdevs[i]) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
if (SELinuxRestoreSecurityImageLabelInt(drv,
|
if (SELinuxRestoreSecurityImageLabelInt(mgr,
|
||||||
vm,
|
vm,
|
||||||
vm->def->disks[i],
|
vm->def->disks[i],
|
||||||
migrated) < 0)
|
migrated) < 0)
|
||||||
@ -801,7 +815,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
@ -825,7 +839,7 @@ SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
@ -839,7 +853,7 @@ SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
@ -853,9 +867,19 @@ SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSecurityVerify(virDomainDefPtr def)
|
SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("security label driver mismatch: "
|
||||||
|
"'%s' model configured for domain, but "
|
||||||
|
"hypervisor driver is '%s'."),
|
||||||
|
secdef->model, virSecurityManagerGetModel(mgr));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
||||||
if (security_check_context(secdef->label) != 0) {
|
if (security_check_context(secdef->label) != 0) {
|
||||||
virSecurityReportError(VIR_ERR_XML_ERROR,
|
virSecurityReportError(VIR_ERR_XML_ERROR,
|
||||||
@ -867,7 +891,7 @@ SELinuxSecurityVerify(virDomainDefPtr def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
|
SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
@ -876,12 +900,12 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
|
|||||||
if (vm->def->seclabel.label == NULL)
|
if (vm->def->seclabel.label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!STREQ(drv->name, secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
"'%s' model configured for domain, but "
|
"'%s' model configured for domain, but "
|
||||||
"hypervisor driver is '%s'."),
|
"hypervisor driver is '%s'."),
|
||||||
secdef->model, drv->name);
|
secdef->model, virSecurityManagerGetModel(mgr));
|
||||||
if (security_getenforce() == 1)
|
if (security_getenforce() == 1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -898,7 +922,7 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
|
SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
@ -911,12 +935,12 @@ SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
|
|||||||
if (vm->def->seclabel.label == NULL)
|
if (vm->def->seclabel.label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!STREQ(drv->name, secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
"'%s' model configured for domain, but "
|
"'%s' model configured for domain, but "
|
||||||
"hypervisor driver is '%s'."),
|
"hypervisor driver is '%s'."),
|
||||||
secdef->model, drv->name);
|
secdef->model, virSecurityManagerGetModel(mgr));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -969,7 +993,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
|
SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
@ -978,12 +1002,12 @@ SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
|
|||||||
if (vm->def->seclabel.label == NULL)
|
if (vm->def->seclabel.label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!STREQ(drv->name, secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
"'%s' model configured for domain, but "
|
"'%s' model configured for domain, but "
|
||||||
"hypervisor driver is '%s'."),
|
"hypervisor driver is '%s'."),
|
||||||
secdef->model, drv->name);
|
secdef->model, virSecurityManagerGetModel(mgr));
|
||||||
if (security_getenforce() == 1)
|
if (security_getenforce() == 1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1011,7 +1035,7 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
|
SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *stdin_path)
|
const char *stdin_path)
|
||||||
{
|
{
|
||||||
@ -1028,12 +1052,12 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
|
|||||||
vm->def->disks[i]->src, vm->def->disks[i]->dst);
|
vm->def->disks[i]->src, vm->def->disks[i]->dst);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (SELinuxSetSecurityImageLabel(drv,
|
if (SELinuxSetSecurityImageLabel(mgr,
|
||||||
vm, vm->def->disks[i]) < 0)
|
vm, vm->def->disks[i]) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
||||||
if (SELinuxSetSecurityHostdevLabel(drv,
|
if (SELinuxSetSecurityHostdevLabel(mgr,
|
||||||
vm,
|
vm,
|
||||||
vm->def->hostdevs[i]) < 0)
|
vm->def->hostdevs[i]) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1063,24 +1087,37 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virSecurityDriver virSELinuxSecurityDriver = {
|
virSecurityDriver virSecurityDriverSELinux = {
|
||||||
.name = SECURITY_SELINUX_NAME,
|
0,
|
||||||
.probe = SELinuxSecurityDriverProbe,
|
SECURITY_SELINUX_NAME,
|
||||||
.open = SELinuxSecurityDriverOpen,
|
SELinuxSecurityDriverProbe,
|
||||||
.domainSecurityVerify = SELinuxSecurityVerify,
|
SELinuxSecurityDriverOpen,
|
||||||
.domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
|
SELinuxSecurityDriverClose,
|
||||||
.domainSetSecuritySocketLabel = SELinuxSetSecuritySocketLabel,
|
|
||||||
.domainClearSecuritySocketLabel = SELinuxClearSecuritySocketLabel,
|
SELinuxSecurityGetModel,
|
||||||
.domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
|
SELinuxSecurityGetDOI,
|
||||||
.domainGenSecurityLabel = SELinuxGenSecurityLabel,
|
|
||||||
.domainReserveSecurityLabel = SELinuxReserveSecurityLabel,
|
SELinuxSecurityVerify,
|
||||||
.domainReleaseSecurityLabel = SELinuxReleaseSecurityLabel,
|
|
||||||
.domainGetSecurityProcessLabel = SELinuxGetSecurityProcessLabel,
|
SELinuxSetSecurityImageLabel,
|
||||||
.domainSetSecurityProcessLabel = SELinuxSetSecurityProcessLabel,
|
SELinuxRestoreSecurityImageLabel,
|
||||||
.domainRestoreSecurityAllLabel = SELinuxRestoreSecurityAllLabel,
|
|
||||||
.domainSetSecurityAllLabel = SELinuxSetSecurityAllLabel,
|
SELinuxSetSecuritySocketLabel,
|
||||||
.domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
|
SELinuxClearSecuritySocketLabel,
|
||||||
.domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
|
|
||||||
.domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
|
SELinuxGenSecurityLabel,
|
||||||
.domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
|
SELinuxReserveSecurityLabel,
|
||||||
|
SELinuxReleaseSecurityLabel,
|
||||||
|
|
||||||
|
SELinuxGetSecurityProcessLabel,
|
||||||
|
SELinuxSetSecurityProcessLabel,
|
||||||
|
|
||||||
|
SELinuxSetSecurityAllLabel,
|
||||||
|
SELinuxRestoreSecurityAllLabel,
|
||||||
|
|
||||||
|
SELinuxSetSecurityHostdevLabel,
|
||||||
|
SELinuxRestoreSecurityHostdevLabel,
|
||||||
|
|
||||||
|
SELinuxSetSavedStateLabel,
|
||||||
|
SELinuxRestoreSavedStateLabel,
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,6 @@
|
|||||||
#ifndef __VIR_SECURITY_SELINUX_H__
|
#ifndef __VIR_SECURITY_SELINUX_H__
|
||||||
# define __VIR_SECURITY_SELINUX_H__
|
# define __VIR_SECURITY_SELINUX_H__
|
||||||
|
|
||||||
extern virSecurityDriver virSELinuxSecurityDriver;
|
extern virSecurityDriver virSecurityDriverSELinux;
|
||||||
|
|
||||||
#endif /* __VIR_SECURITY_SELINUX_H__ */
|
#endif /* __VIR_SECURITY_SELINUX_H__ */
|
||||||
|
401
src/security/security_stack.c
Normal file
401
src/security/security_stack.c
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Stacked security driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "security_stack.h"
|
||||||
|
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
||||||
|
|
||||||
|
typedef struct _virSecurityStackData virSecurityStackData;
|
||||||
|
typedef virSecurityStackData *virSecurityStackDataPtr;
|
||||||
|
|
||||||
|
struct _virSecurityStackData {
|
||||||
|
virSecurityManagerPtr primary;
|
||||||
|
virSecurityManagerPtr secondary;
|
||||||
|
};
|
||||||
|
|
||||||
|
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr primary)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
priv->primary = primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr secondary)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
priv->secondary = secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virSecurityDriverStatus
|
||||||
|
virSecurityStackProbe(void)
|
||||||
|
{
|
||||||
|
return SECURITY_DRIVER_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
virSecurityStackGetModel(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityManagerGetModel(priv->primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
return virSecurityManagerGetDOI(priv->primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackVerify(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerVerify(priv->primary, def) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
if (virSecurityManagerVerify(priv->secondary, def) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* We don't allow secondary drivers to generate labels.
|
||||||
|
* This may have to change in the future, but requires
|
||||||
|
* changes elsewhere in domain_conf.c and capabilities.c
|
||||||
|
* XML formats first, to allow recording of multiple
|
||||||
|
* labels
|
||||||
|
*/
|
||||||
|
if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#if 0
|
||||||
|
/* XXX See note in GenLabel */
|
||||||
|
if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerReserveLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#if 0
|
||||||
|
/* XXX See note in GenLabel */
|
||||||
|
if (virSecurityManagerReserveLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDiskDefPtr disk)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainHostdevDefPtr dev)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *stdin_path)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
int migrated)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *savefile)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virSecurityLabelPtr seclabel)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (virSecurityManagerGetProcessLabel(priv->secondary, vm, seclabel) < 0)
|
||||||
|
rc = -1;
|
||||||
|
#endif
|
||||||
|
if (virSecurityManagerGetProcessLabel(priv->primary, vm, seclabel) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virSecurityDriver virSecurityDriverStack = {
|
||||||
|
sizeof(virSecurityStackData),
|
||||||
|
"stack",
|
||||||
|
virSecurityStackProbe,
|
||||||
|
virSecurityStackOpen,
|
||||||
|
virSecurityStackClose,
|
||||||
|
|
||||||
|
virSecurityStackGetModel,
|
||||||
|
virSecurityStackGetDOI,
|
||||||
|
|
||||||
|
virSecurityStackVerify,
|
||||||
|
|
||||||
|
virSecurityStackSetSecurityImageLabel,
|
||||||
|
virSecurityStackRestoreSecurityImageLabel,
|
||||||
|
|
||||||
|
virSecurityStackSetSocketLabel,
|
||||||
|
virSecurityStackClearSocketLabel,
|
||||||
|
|
||||||
|
virSecurityStackGenLabel,
|
||||||
|
virSecurityStackReserveLabel,
|
||||||
|
virSecurityStackReleaseLabel,
|
||||||
|
|
||||||
|
virSecurityStackGetProcessLabel,
|
||||||
|
virSecurityStackSetProcessLabel,
|
||||||
|
|
||||||
|
virSecurityStackSetSecurityAllLabel,
|
||||||
|
virSecurityStackRestoreSecurityAllLabel,
|
||||||
|
|
||||||
|
virSecurityStackSetSecurityHostdevLabel,
|
||||||
|
virSecurityStackRestoreSecurityHostdevLabel,
|
||||||
|
|
||||||
|
virSecurityStackSetSavedStateLabel,
|
||||||
|
virSecurityStackRestoreSavedStateLabel,
|
||||||
|
};
|
33
src/security/security_stack.h
Normal file
33
src/security/security_stack.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Stacked security driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "security_driver.h"
|
||||||
|
|
||||||
|
#ifndef __VIR_SECURITY_STACK
|
||||||
|
# define __VIR_SECURITY_STACK
|
||||||
|
|
||||||
|
extern virSecurityDriver virSecurityDriverStack;
|
||||||
|
|
||||||
|
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr primary);
|
||||||
|
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr secondary);
|
||||||
|
|
||||||
|
#endif /* __VIR_SECURITY_DAC */
|
@ -10,22 +10,16 @@
|
|||||||
int
|
int
|
||||||
main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int ret;
|
virSecurityManagerPtr mgr;
|
||||||
|
|
||||||
const char *doi, *model;
|
const char *doi, *model;
|
||||||
virSecurityDriverPtr security_drv;
|
|
||||||
|
|
||||||
ret = virSecurityDriverStartup (&security_drv, "selinux", false);
|
mgr = virSecurityManagerNew(NULL, false);
|
||||||
if (ret == -1)
|
if (mgr == NULL) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Failed to start security driver");
|
fprintf (stderr, "Failed to start security driver");
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
/* No security driver wanted to be enabled: just return */
|
|
||||||
if (ret == -2)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
model = virSecurityDriverGetModel (security_drv);
|
model = virSecurityManagerGetModel(mgr);
|
||||||
if (!model)
|
if (!model)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Failed to copy secModel model: %s",
|
fprintf (stderr, "Failed to copy secModel model: %s",
|
||||||
@ -33,7 +27,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
|||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
doi = virSecurityDriverGetDOI (security_drv);
|
doi = virSecurityManagerGetDOI(mgr);
|
||||||
if (!doi)
|
if (!doi)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Failed to copy secModel DOI: %s",
|
fprintf (stderr, "Failed to copy secModel DOI: %s",
|
||||||
@ -41,5 +35,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
|||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virSecurityManagerFree(mgr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user