From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> For the sake of backwards compat, LXC guests are *not* confined by default. This is because it is not practical to dynamically relabel containers using large filesystem trees. Applications can create confined containers though, by giving suitable XML configs * src/Makefile.am: Link libvirt_lxc to security drivers * src/lxc/libvirtd_lxc.aug, src/lxc/lxc_conf.h, src/lxc/lxc_conf.c, src/lxc/lxc.conf, src/lxc/test_libvirtd_lxc.aug: Config file handling for security driver * src/lxc/lxc_driver.c: Wire up security driver functions * src/lxc/lxc_controller.c: Add a '--security' flag to specify which security driver to activate * src/lxc/lxc_container.c, src/lxc/lxc_container.h: Set the process label just before exec'ing init. --- src/Makefile.am | 13 +++ src/lxc/libvirtd_lxc.aug | 15 +++- src/lxc/lxc.conf | 18 ++++ src/lxc/lxc_conf.c | 62 ++++++++++++-- src/lxc/lxc_conf.h | 8 ++- src/lxc/lxc_container.c | 9 ++- src/lxc/lxc_container.h | 2 + src/lxc/lxc_controller.c | 28 +++++- src/lxc/lxc_driver.c | 193 ++++++++++++++++++++++++++++++++++++++++- src/lxc/test_libvirtd_lxc.aug | 2 + 10 files changed, 335 insertions(+), 15 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a44446f..7f1c80f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1503,7 +1503,14 @@ libvirt_lxc_SOURCES = \ $(DOMAIN_CONF_SOURCES) \ $(SECRET_CONF_SOURCES) \ $(CPU_CONF_SOURCES) \ + $(SECURITY_DRIVER_SOURCES) \ $(NWFILTER_PARAM_CONF_SOURCES) +if WITH_SECDRIVER_SELINUX +libvirt_lxc_SOURCES += $(SECURITY_DRIVER_SELINUX_SOURCES) +endif +if WITH_SECDRIVER_APPARMOR +libvirt_lxc_SOURCES += $(SECURITY_DRIVER_APPARMOR_SOURCES) +endif libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS) libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \ $(LIBXML_LIBS) $(NUMACTL_LIBS) $(THREAD_LIBS) \ @@ -1513,6 +1520,9 @@ libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \ if WITH_DTRACE libvirt_lxc_LDADD += probes.o endif +if WITH_SECDRIVER_SELINUX +libvirt_lxc_LDADD += $(SELINUX_LIBS) +endif libvirt_lxc_CFLAGS = \ $(LIBPARTED_CFLAGS) \ $(NUMACTL_CFLAGS) \ @@ -1525,6 +1535,9 @@ if HAVE_LIBBLKID libvirt_lxc_CFLAGS += $(BLKID_CFLAGS) libvirt_lxc_LDADD += $(BLKID_LIBS) endif +if WITH_SECDRIVER_SELINUX +libvirt_lxc_CFLAGS += $(SELINUX_CFLAGS) +endif endif endif EXTRA_DIST += $(LXC_CONTROLLER_SOURCES) diff --git a/src/lxc/libvirtd_lxc.aug b/src/lxc/libvirtd_lxc.aug index 10f25e4..be6402c 100644 --- a/src/lxc/libvirtd_lxc.aug +++ b/src/lxc/libvirtd_lxc.aug @@ -7,13 +7,26 @@ module Libvirtd_lxc = let value_sep = del /[ \t]*=[ \t]*/ " = " let indent = del /[ \t]*/ "" + let array_sep = del /,[ \t\n]*/ ", " + let array_start = del /\[[ \t\n]*/ "[ " + let array_end = del /\]/ "]" + + let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" let bool_val = store /0|1/ + let int_val = store /[0-9]+/ + let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ "" + let str_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end + let str_entry (kw:string) = [ key kw . value_sep . str_val ] let bool_entry (kw:string) = [ key kw . value_sep . bool_val ] - + let int_entry (kw:string) = [ key kw . value_sep . int_val ] + let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ] (* Config entry grouped by function - same order as example config *) let log_entry = bool_entry "log_with_libvirtd" + | str_entry "security_driver" + | bool_entry "security_default_confined" + | bool_entry "security_require_confined" (* Each enty in the config is one of the following three ... *) let entry = log_entry diff --git a/src/lxc/lxc.conf b/src/lxc/lxc.conf index 7a5066f..09dc95f 100644 --- a/src/lxc/lxc.conf +++ b/src/lxc/lxc.conf @@ -11,3 +11,21 @@ # This is disabled by default, uncomment below to enable it. # # log_with_libvirtd = 1 + + +# The default security driver is SELinux. If SELinux is disabled +# on the host, then the security driver will automatically disable +# itself. If you wish to disable QEMU SELinux security driver while +# leaving SELinux enabled for the host in general, then set this +# to 'none' instead. +# +# security_driver = "selinux" + +# If set to non-zero, then the default security labeling +# will make guests confined. If set to zero, then guests +# will be unconfined by default. Defaults to 0. +# security_default_confined = 1 + +# If set to non-zero, then attempts to create unconfined +# guests will be blocked. Defaults to 0. +# security_require_confined = 1 diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c index e842736..72547c4 100644 --- a/src/lxc/lxc_conf.c +++ b/src/lxc/lxc_conf.c @@ -49,7 +49,7 @@ static int lxcDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED) /* Functions */ -virCapsPtr lxcCapsInit(void) +virCapsPtr lxcCapsInit(lxc_driver_t *driver) { struct utsname utsname; virCapsPtr caps; @@ -127,8 +127,30 @@ virCapsPtr lxcCapsInit(void) /* LXC Requires an emulator in the XML */ virCapabilitiesSetEmulatorRequired(caps); + if (driver) { + /* Security driver data */ + const char *doi, *model; + + doi = virSecurityManagerGetDOI(driver->securityManager); + model = virSecurityManagerGetModel(driver->securityManager); + if (STRNEQ(model, "none")) { + if (!(caps->host.secModel.model = strdup(model))) + goto no_memory; + if (!(caps->host.secModel.doi = strdup(doi))) + goto no_memory; + } + + VIR_DEBUG("Initialized caps for security driver \"%s\" with " + "DOI \"%s\"", model, doi); + } else { + VIR_INFO("No driver, not initializing security driver"); + } + return caps; +no_memory: + virReportOOMError(); + error: virCapabilitiesFree(caps); return NULL; @@ -140,6 +162,9 @@ int lxcLoadDriverConfig(lxc_driver_t *driver) virConfPtr conf; virConfValuePtr p; + driver->securityDefaultConfined = false; + driver->securityRequireConfined = false; + /* Set the container configuration directory */ if ((driver->configDir = strdup(LXC_CONFIG_DIR)) == NULL) goto no_memory; @@ -161,14 +186,39 @@ int lxcLoadDriverConfig(lxc_driver_t *driver) if (!conf) goto done; +#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \ + lxcError(VIR_ERR_INTERNAL_ERROR, \ + "%s: %s: expected type " #typ, \ + filename, (name)); \ + virConfFree(conf); \ + return -1; \ + } + p = virConfGetValue(conf, "log_with_libvirtd"); - if (p) { - if (p->type != VIR_CONF_LONG) - VIR_WARN("lxcLoadDriverConfig: invalid setting: log_with_libvirtd"); - else - driver->log_libvirtd = p->l; + CHECK_TYPE ("log_with_libvirtd", VIR_CONF_LONG); + if (p) driver->log_libvirtd = p->l; + + p = virConfGetValue (conf, "security_driver"); + CHECK_TYPE ("security_driver", VIR_CONF_STRING); + if (p && p->str) { + if (!(driver->securityDriverName = strdup(p->str))) { + virReportOOMError(); + virConfFree(conf); + return -1; + } } + p = virConfGetValue (conf, "security_default_confined"); + CHECK_TYPE ("security_default_confined", VIR_CONF_LONG); + if (p) driver->securityDefaultConfined = p->l; + + p = virConfGetValue (conf, "security_require_confined"); + CHECK_TYPE ("security_require_confined", VIR_CONF_LONG); + if (p) driver->securityRequireConfined = p->l; + + +#undef CHECK_TYPE + virConfFree(conf); done: diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h index b124330..ebdc173 100644 --- a/src/lxc/lxc_conf.h +++ b/src/lxc/lxc_conf.h @@ -33,6 +33,7 @@ # include "capabilities.h" # include "threads.h" # include "cgroup.h" +# include "security/security_manager.h" # include "configmake.h" # define LXC_CONFIG_DIR SYSCONFDIR "/libvirt/lxc" @@ -57,6 +58,11 @@ struct __lxc_driver { virDomainEventStatePtr domainEventState; + char *securityDriverName; + bool securityDefaultConfined; + bool securityRequireConfined; + virSecurityManagerPtr securityManager; + /* Mapping of 'char *uuidstr' -> virConnectPtr * of guests which will be automatically killed * when the virConnectPtr is closed*/ @@ -64,7 +70,7 @@ struct __lxc_driver { }; int lxcLoadDriverConfig(lxc_driver_t *driver); -virCapsPtr lxcCapsInit(void); +virCapsPtr lxcCapsInit(lxc_driver_t *driver); # define lxcError(code, ...) \ virReportErrorHelper(VIR_FROM_LXC, code, __FILE__, \ diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index dcd65ef..b0493fd 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -91,6 +91,7 @@ typedef char lxc_message_t; typedef struct __lxc_child_argv lxc_child_argv_t; struct __lxc_child_argv { virDomainDefPtr config; + virSecurityManagerPtr securityDriver; unsigned int nveths; char **veths; int monitor; @@ -1296,6 +1297,10 @@ static int lxcContainerChild( void *data ) goto cleanup; } + VIR_DEBUG("Setting up security labeling"); + if (virSecurityManagerSetProcessLabel(argv->securityDriver, vmDef) < 0) + goto cleanup; + ret = 0; cleanup: VIR_FREE(ttyPath); @@ -1358,6 +1363,7 @@ const char *lxcContainerGetAlt32bitArch(const char *arch) * Returns PID of container on success or -1 in case of error */ int lxcContainerStart(virDomainDefPtr def, + virSecurityManagerPtr securityDriver, unsigned int nveths, char **veths, int control, @@ -1369,7 +1375,8 @@ int lxcContainerStart(virDomainDefPtr def, int cflags; int stacksize = getpagesize() * 4; char *stack, *stacktop; - lxc_child_argv_t args = { def, nveths, veths, control, + lxc_child_argv_t args = { def, securityDriver, + nveths, veths, control, ttyPaths, nttyPaths, handshakefd}; /* allocate a stack for the container */ diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h index ffeda5e..77fb9b2 100644 --- a/src/lxc/lxc_container.h +++ b/src/lxc/lxc_container.h @@ -25,6 +25,7 @@ # define LXC_CONTAINER_H # include "lxc_conf.h" +# include "security/security_manager.h" enum { LXC_CONTAINER_FEATURE_NET = (1 << 0), @@ -49,6 +50,7 @@ int lxcContainerSendContinue(int control); int lxcContainerWaitForContinue(int control); int lxcContainerStart(virDomainDefPtr def, + virSecurityManagerPtr securityDriver, unsigned int nveths, char **veths, int control, diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 49727dd..cb04b08 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1361,6 +1361,7 @@ cleanup: static int lxcControllerRun(virDomainDefPtr def, + virSecurityManagerPtr securityDriver, unsigned int nveths, char **veths, int monitor, @@ -1515,6 +1516,7 @@ lxcControllerRun(virDomainDefPtr def, goto cleanup; if ((container = lxcContainerStart(def, + securityDriver, nveths, veths, control[1], @@ -1623,11 +1625,13 @@ int main(int argc, char *argv[]) { "veth", 1, NULL, 'v' }, { "console", 1, NULL, 'c' }, { "handshakefd", 1, NULL, 's' }, + { "security", 1, NULL, 'S' }, { "help", 0, NULL, 'h' }, { 0, 0, 0, 0 }, }; int *ttyFDs = NULL; size_t nttyFDs = 0; + virSecurityManagerPtr securityDriver = NULL; if (setlocale(LC_ALL, "") == NULL || bindtextdomain(PACKAGE, LOCALEDIR) == NULL || @@ -1639,7 +1643,7 @@ int main(int argc, char *argv[]) while (1) { int c; - c = getopt_long(argc, argv, "dn:v:m:c:s:h", + c = getopt_long(argc, argv, "dn:v:m:c:s:h:S:", options, NULL); if (c == -1) @@ -1687,6 +1691,14 @@ int main(int argc, char *argv[]) } break; + case 'S': + if (!(securityDriver = virSecurityManagerNew(optarg, false, false, false))) { + fprintf(stderr, "Cannot create security manager '%s'", + optarg); + goto cleanup; + } + break; + case 'h': case '?': fprintf(stderr, "\n"); @@ -1699,12 +1711,20 @@ int main(int argc, char *argv[]) fprintf(stderr, " -c FD, --console FD\n"); fprintf(stderr, " -v VETH, --veth VETH\n"); fprintf(stderr, " -s FD, --handshakefd FD\n"); + fprintf(stderr, " -S NAME, --security NAME\n"); fprintf(stderr, " -h, --help\n"); fprintf(stderr, "\n"); goto cleanup; } } + if (securityDriver == NULL) { + if (!(securityDriver = virSecurityManagerNew("none", false, false, false))) { + fprintf(stderr, "%s: cannot initialize nop security manager", argv[0]); + goto cleanup; + } + } + if (name == NULL) { fprintf(stderr, "%s: missing --name argument for configuration\n", argv[0]); @@ -1724,7 +1744,7 @@ int main(int argc, char *argv[]) virEventRegisterDefaultImpl(); - if ((caps = lxcCapsInit()) == NULL) + if ((caps = lxcCapsInit(NULL)) == NULL) goto cleanup; if ((configFile = virDomainConfigFile(LXC_STATE_DIR, @@ -1790,10 +1810,10 @@ int main(int argc, char *argv[]) goto cleanup; } - rc = lxcControllerRun(def, nveths, veths, monitor, client, + rc = lxcControllerRun(def, securityDriver, + nveths, veths, monitor, client, ttyFDs, nttyFDs, handshakefd); - cleanup: if (def) virPidFileDelete(LXC_STATE_DIR, def->name); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index e6cc90d..b712da4 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -441,6 +441,9 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml) VIR_DOMAIN_XML_INACTIVE))) goto cleanup; + if (virSecurityManagerVerify(driver->securityManager, def) < 0) + goto cleanup; + if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0) goto cleanup; @@ -1394,7 +1397,21 @@ static int lxcMonitorClient(lxc_driver_t * driver, return -1; } - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0) { + VIR_ERROR(_("Failed to set security context for monitor for %s"), + vm->def->name); + goto error; + } + + fd = socket(PF_UNIX, SOCK_STREAM, 0); + + if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) { + VIR_ERROR(_("Failed to clear security context for monitor for %s"), + vm->def->name); + goto error; + } + + if (fd < 0) { virReportSystemError(errno, "%s", _("Failed to create client socket")); goto error; @@ -1437,6 +1454,16 @@ static int lxcVmTerminate(lxc_driver_t *driver, return -1; } + virSecurityManagerRestoreAllLabel(driver->securityManager, + vm->def, false); + virSecurityManagerReleaseLabel(driver->securityManager, vm->def); + /* Clear out dynamically assigned labels */ + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + VIR_FREE(vm->def->seclabel.model); + VIR_FREE(vm->def->seclabel.label); + VIR_FREE(vm->def->seclabel.imagelabel); + } + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) == 0) { rc = virCgroupKillPainfully(group); if (rc < 0) { @@ -1567,6 +1594,10 @@ lxcBuildControllerCmd(lxc_driver_t *driver, virCommandAddArgFormat(cmd, "%d", ttyFDs[i]); virCommandPreserveFD(cmd, ttyFDs[i]); } + + if (driver->securityDriverName) + virCommandAddArgPair(cmd, "--security", driver->securityDriverName); + virCommandAddArg(cmd, "--handshake"); virCommandAddArgFormat(cmd, "%d", handshakefd); virCommandAddArg(cmd, "--background"); @@ -1761,6 +1792,24 @@ static int lxcVmStart(virConnectPtr conn, virReportOOMError(); goto cleanup; } + + /* If you are using a SecurityDriver with dynamic labelling, + then generate a security label for isolation */ + VIR_DEBUG("Generating domain security label (if required)"); + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DEFAULT) + vm->def->seclabel.type = VIR_DOMAIN_SECLABEL_NONE; + + if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) { + virDomainAuditSecurityLabel(vm, false); + goto cleanup; + } + virDomainAuditSecurityLabel(vm, true); + + VIR_DEBUG("Setting domain security labels"); + if (virSecurityManagerSetAllLabel(driver->securityManager, + vm->def, NULL) < 0) + goto cleanup; + for (i = 0 ; i < vm->def->nconsoles ; i++) ttyFDs[i] = -1; @@ -1916,6 +1965,16 @@ cleanup: if (rc != 0) { VIR_FORCE_CLOSE(priv->monitor); virDomainConfVMNWFilterTeardown(vm); + + virSecurityManagerRestoreAllLabel(driver->securityManager, + vm->def, false); + virSecurityManagerReleaseLabel(driver->securityManager, vm->def); + /* Clear out dynamically assigned labels */ + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + VIR_FREE(vm->def->seclabel.model); + VIR_FREE(vm->def->seclabel.label); + VIR_FREE(vm->def->seclabel.imagelabel); + } } for (i = 0 ; i < nttyFDs ; i++) VIR_FORCE_CLOSE(ttyFDs[i]); @@ -2040,6 +2099,9 @@ lxcDomainCreateAndStart(virConnectPtr conn, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; + if (virSecurityManagerVerify(driver->securityManager, def) < 0) + goto cleanup; + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; @@ -2084,6 +2146,102 @@ cleanup: } +static int lxcDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel) +{ + lxc_driver_t *driver = dom->conn->privateData; + virDomainObjPtr vm; + int ret = -1; + + lxcDriverLock(driver); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + memset(seclabel, 0, sizeof(*seclabel)); + + if (!vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(dom->uuid, uuidstr); + lxcError(VIR_ERR_NO_DOMAIN, + _("no domain with matching uuid '%s'"), uuidstr); + goto cleanup; + } + + if (!virDomainVirtTypeToString(vm->def->virtType)) { + lxcError(VIR_ERR_INTERNAL_ERROR, + _("unknown virt type in domain definition '%d'"), + vm->def->virtType); + goto cleanup; + } + + /* + * Theoretically, the pid can be replaced during this operation and + * return the label of a different process. If atomicity is needed, + * further validation will be required. + * + * Comment from Dan Berrange: + * + * Well the PID as stored in the virDomainObjPtr can't be changed + * because you've got a locked object. The OS level PID could have + * exited, though and in extreme circumstances have cycled through all + * PIDs back to ours. We could sanity check that our PID still exists + * after reading the label, by checking that our FD connecting to the + * LXC monitor hasn't seen SIGHUP/ERR on poll(). + */ + if (virDomainObjIsActive(vm)) { + if (virSecurityManagerGetProcessLabel(driver->securityManager, + vm->def, vm->pid, seclabel) < 0) { + lxcError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Failed to get security label")); + goto cleanup; + } + } + + ret = 0; + +cleanup: + if (vm) + virDomainObjUnlock(vm); + lxcDriverUnlock(driver); + return ret; +} + +static int lxcNodeGetSecurityModel(virConnectPtr conn, + virSecurityModelPtr secmodel) +{ + lxc_driver_t *driver = conn->privateData; + int ret = 0; + + lxcDriverLock(driver); + 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; + + if (!virStrcpy(secmodel->model, driver->caps->host.secModel.model, + VIR_SECURITY_MODEL_BUFLEN)) { + lxcError(VIR_ERR_INTERNAL_ERROR, + _("security model string exceeds max %d bytes"), + VIR_SECURITY_MODEL_BUFLEN - 1); + ret = -1; + goto cleanup; + } + + if (!virStrcpy(secmodel->doi, driver->caps->host.secModel.doi, + VIR_SECURITY_DOI_BUFLEN)) { + lxcError(VIR_ERR_INTERNAL_ERROR, + _("security DOI string exceeds max %d bytes"), + VIR_SECURITY_DOI_BUFLEN-1); + ret = -1; + goto cleanup; + } + +cleanup: + lxcDriverUnlock(driver); + return ret; +} + + static int lxcDomainEventRegister(virConnectPtr conn, virConnectDomainEventCallback callback, @@ -2332,6 +2490,10 @@ lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) lxcMonitorEvent, vm, NULL)) < 0) goto error; + + if (virSecurityManagerReserveLabel(driver->securityManager, + vm->def, vm->pid) < 0) + goto error; } else { vm->def->id = -1; VIR_FORCE_CLOSE(priv->monitor); @@ -2348,6 +2510,27 @@ error: } +static int +lxcSecurityInit(lxc_driver_t *driver) +{ + virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName, + false, + driver->securityDefaultConfined, + driver->securityRequireConfined); + if (!mgr) + goto error; + + driver->securityManager = mgr; + + return 0; + +error: + VIR_ERROR(_("Failed to initialize security drivers")); + virSecurityManagerFree(mgr); + return -1; +} + + static int lxcStartup(int privileged) { char *ld; @@ -2408,7 +2591,10 @@ static int lxcStartup(int privileged) if (lxcLoadDriverConfig(lxc_driver) < 0) goto cleanup; - if ((lxc_driver->caps = lxcCapsInit()) == NULL) + if (lxcSecurityInit(lxc_driver) < 0) + goto cleanup; + + if ((lxc_driver->caps = lxcCapsInit(lxc_driver)) == NULL) goto cleanup; lxc_driver->caps->privateDataAllocFunc = lxcDomainObjPrivateAlloc; @@ -2500,6 +2686,7 @@ static int lxcShutdown(void) lxcProcessAutoDestroyShutdown(lxc_driver); virCapabilitiesFree(lxc_driver->caps); + virSecurityManagerFree(lxc_driver->securityManager); VIR_FREE(lxc_driver->configDir); VIR_FREE(lxc_driver->autostartDir); VIR_FREE(lxc_driver->stateDir); @@ -3671,6 +3858,8 @@ static virDriver lxcDriver = { .domainGetBlkioParameters = lxcDomainGetBlkioParameters, /* 0.9.8 */ .domainGetInfo = lxcDomainGetInfo, /* 0.4.2 */ .domainGetState = lxcDomainGetState, /* 0.9.2 */ + .domainGetSecurityLabel = lxcDomainGetSecurityLabel, /* 0.9.10 */ + .nodeGetSecurityModel = lxcNodeGetSecurityModel, /* 0.9.10 */ .domainGetXMLDesc = lxcDomainGetXMLDesc, /* 0.4.2 */ .listDefinedDomains = lxcListDefinedDomains, /* 0.4.2 */ .numOfDefinedDomains = lxcNumDefinedDomains, /* 0.4.2 */ diff --git a/src/lxc/test_libvirtd_lxc.aug b/src/lxc/test_libvirtd_lxc.aug index e757b82..f8544a0 100644 --- a/src/lxc/test_libvirtd_lxc.aug +++ b/src/lxc/test_libvirtd_lxc.aug @@ -13,6 +13,7 @@ module Test_libvirtd_lxc = # This is disabled by default, uncomment below to enable it. # log_with_libvirtd = 1 +security_driver = \"selinux\" " test Libvirtd_lxc.lns get conf = @@ -29,3 +30,4 @@ log_with_libvirtd = 1 { "#comment" = "This is disabled by default, uncomment below to enable it." } { "#comment" = "" } { "log_with_libvirtd" = "1" } +{ "security_driver" = "selinux" } -- 1.7.7.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list