Add two new security label types

Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.

With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.

This patch introduces two new security label types

 - default:  the host configuration decides whether to run the
             guest with type 'none' or 'dynamic' at guest start
 - none:     the guest will run unconfined by security policy

The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement

  security_default_confined = 1|0  (default == 1)
  security_require_confined = 1|0  (default == 0)

* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
  seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
  Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
  src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
  config
This commit is contained in:
Daniel P. Berrange 2012-01-25 14:12:52 +00:00 committed by Eric Blake
parent 87c39f0e20
commit b170eb99f5
14 changed files with 181 additions and 50 deletions

View File

@ -3539,16 +3539,18 @@ qemu-kvm -net nic,model=? /dev/null
<p> <p>
The <code>seclabel</code> element allows control over the The <code>seclabel</code> element allows control over the
operation of the security drivers. There are two basic operation of the security drivers. There are three basic
modes of operation, dynamic where libvirt automatically modes of operation, 'dynamic' where libvirt automatically
generates a unique security label, or static where the generates a unique security label, 'static' where the
application/administrator chooses the labels. With dynamic application/administrator chooses the labels, or 'none'
where confinement is disabled. With dynamic
label generation, libvirt will always automatically label generation, libvirt will always automatically
relabel any resources associated with the virtual machine. relabel any resources associated with the virtual machine.
With static label assignment, by default, the administrator With static label assignment, by default, the administrator
or application must ensure labels are set correctly on any or application must ensure labels are set correctly on any
resources, however, automatic relabeling can be enabled resources, however, automatic relabeling can be enabled
if desired. if desired. <span class="since">'dynamic' since 0.6.1, 'static'
since 0.6.2, and 'none' since 0.9.10.</span>
</p> </p>
<p> <p>
@ -3570,8 +3572,17 @@ qemu-kvm -net nic,model=? /dev/null
&lt;seclabel type='static' model='selinux' relabel='yes'&gt; &lt;seclabel type='static' model='selinux' relabel='yes'&gt;
&lt;label&gt;system_u:system_r:svirt_t:s0:c392,c662&lt;/label&gt; &lt;label&gt;system_u:system_r:svirt_t:s0:c392,c662&lt;/label&gt;
&lt;/seclabel&gt; &lt;/seclabel&gt;
&lt;seclabel type='none'/&gt;
</pre> </pre>
<p>
If no 'type' attribute is provided in the input XML, then
the security driver default setting will be used, which
may be either 'none' or 'dynamic'. If a 'baselabel' is set
but no 'type' is set, then the type is presumed to be 'dynamic'
</p>
<p> <p>
When viewing the XML for a running guest with automatic When viewing the XML for a running guest with automatic
resource relabeling active, an additional XML element, resource relabeling active, an additional XML element,
@ -3581,9 +3592,9 @@ qemu-kvm -net nic,model=? /dev/null
</p> </p>
<dl> <dl>
<dt><code>type</code></dt> <dt><code>type</code></dt>
<dd>Either <code>static</code> or <code>dynamic</code> to determine <dd>Either <code>static</code>, <code>dynamic</code> or <code>none</code>
whether libvirt automatically generates a unique security label to determine whether libvirt automatically generates a unique security
or not. label or not.
</dd> </dd>
<dt><code>model</code></dt> <dt><code>model</code></dt>
<dd>A valid security model name, matching the currently <dd>A valid security model name, matching the currently

View File

@ -129,6 +129,11 @@
</optional> </optional>
</interleave> </interleave>
</group> </group>
<group>
<attribute name='type'>
<value>none</value>
</attribute>
</group>
</choice> </choice>
</element> </element>
</define> </define>

View File

@ -90,6 +90,7 @@ src/secret/secret_driver.c
src/security/security_apparmor.c src/security/security_apparmor.c
src/security/security_dac.c src/security/security_dac.c
src/security/security_driver.c src/security/security_driver.c
src/security/security_manager.c
src/security/security_selinux.c src/security/security_selinux.c
src/security/virt-aa-helper.c src/security/virt-aa-helper.c
src/storage/parthelper.c src/storage/parthelper.c

View File

@ -564,6 +564,8 @@ VIR_ENUM_IMPL(virDomainCrashedReason, VIR_DOMAIN_CRASHED_LAST,
"unknown") "unknown")
VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST, VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
"default",
"none",
"dynamic", "dynamic",
"static") "static")
@ -2585,13 +2587,15 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
"%s", _("missing security type")); "%s", _("missing security type"));
goto error; goto error;
} }
def->type = virDomainSeclabelTypeFromString(p); def->type = virDomainSeclabelTypeFromString(p);
VIR_FREE(p); VIR_FREE(p);
if (def->type < 0) { if (def->type <= 0) {
virDomainReportError(VIR_ERR_XML_ERROR, virDomainReportError(VIR_ERR_XML_ERROR,
"%s", _("invalid security type")); "%s", _("invalid security type"));
goto error; goto error;
} }
p = virXPathStringLimit("string(./seclabel/@relabel)", p = virXPathStringLimit("string(./seclabel/@relabel)",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt); VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p != NULL) { if (p != NULL) {
@ -2612,8 +2616,15 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
"%s", _("dynamic label type must use resource relabeling")); "%s", _("dynamic label type must use resource relabeling"));
goto error; goto error;
} }
if (def->type == VIR_DOMAIN_SECLABEL_NONE &&
!def->norelabel) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("resource relabeling is not compatible with 'none' label type"));
goto error;
}
} else { } else {
if (def->type == VIR_DOMAIN_SECLABEL_STATIC) if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
def->type == VIR_DOMAIN_SECLABEL_NONE)
def->norelabel = true; def->norelabel = true;
else else
def->norelabel = false; def->norelabel = false;
@ -2648,12 +2659,16 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
def->imagelabel = p; def->imagelabel = p;
} }
/* Only parse baselabel, for dynamic label */ /* Only parse baselabel, for dynamic or none label types */
if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC ||
def->type == VIR_DOMAIN_SECLABEL_NONE) {
p = virXPathStringLimit("string(./seclabel/baselabel[1])", p = virXPathStringLimit("string(./seclabel/baselabel[1])",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt); VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p != NULL) if (p != NULL) {
def->baselabel = p; def->baselabel = p;
/* Forces none type to dynamic for back compat */
def->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
}
} }
/* Only parse model, if static labelling, or a base /* Only parse model, if static labelling, or a base
@ -9923,24 +9938,32 @@ virDomainLifecycleDefFormat(virBufferPtr buf,
} }
static int static void
virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def, virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
unsigned int flags)
{ {
const char *sectype = virDomainSeclabelTypeToString(def->type); const char *sectype = virDomainSeclabelTypeToString(def->type);
int ret = -1;
if (!sectype) if (!sectype)
goto cleanup; return;
if (def->type == VIR_DOMAIN_SECLABEL_DEFAULT)
return;
virBufferAsprintf(buf, "<seclabel type='%s'",
sectype);
virBufferEscapeString(buf, " model='%s'", def->model);
virBufferAsprintf(buf, " relabel='%s'",
def->norelabel ? "no" : "yes");
if (def->type == VIR_DOMAIN_SECLABEL_NONE) {
virBufferAddLit(buf, "/>\n");
return;
}
if (def->label || def->imagelabel || def->baselabel) {
virBufferAddLit(buf, ">\n");
if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
!def->baselabel &&
(flags & VIR_DOMAIN_XML_INACTIVE)) {
/* This is the default for inactive xml, so nothing to output. */
} else {
virBufferAsprintf(buf, "<seclabel type='%s' model='%s' relabel='%s'>\n",
sectype, def->model,
def->norelabel ? "no" : "yes");
virBufferEscapeString(buf, " <label>%s</label>\n", virBufferEscapeString(buf, " <label>%s</label>\n",
def->label); def->label);
if (!def->norelabel) if (!def->norelabel)
@ -9950,10 +9973,9 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def,
virBufferEscapeString(buf, " <baselabel>%s</baselabel>\n", virBufferEscapeString(buf, " <baselabel>%s</baselabel>\n",
def->baselabel); def->baselabel);
virBufferAddLit(buf, "</seclabel>\n"); virBufferAddLit(buf, "</seclabel>\n");
} else {
virBufferAddLit(buf, "/>\n");
} }
ret = 0;
cleanup:
return ret;
} }
@ -11957,12 +11979,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, " </devices>\n"); virBufferAddLit(buf, " </devices>\n");
if (def->seclabel.model) { virBufferAdjustIndent(buf, 2);
virBufferAdjustIndent(buf, 2); virSecurityLabelDefFormat(buf, &def->seclabel);
if (virSecurityLabelDefFormat(buf, &def->seclabel, flags) < 0) virBufferAdjustIndent(buf, -2);
goto cleanup;
virBufferAdjustIndent(buf, -2);
}
if (def->namespaceData && def->ns.format) { if (def->namespaceData && def->ns.format) {
if ((def->ns.format)(buf, def->namespaceData) < 0) if ((def->ns.format)(buf, def->namespaceData) < 0)

View File

@ -175,6 +175,8 @@ struct _virDomainDeviceInfo {
}; };
enum virDomainSeclabelType { enum virDomainSeclabelType {
VIR_DOMAIN_SECLABEL_DEFAULT,
VIR_DOMAIN_SECLABEL_NONE,
VIR_DOMAIN_SECLABEL_DYNAMIC, VIR_DOMAIN_SECLABEL_DYNAMIC,
VIR_DOMAIN_SECLABEL_STATIC, VIR_DOMAIN_SECLABEL_STATIC,

View File

@ -33,6 +33,8 @@ module Libvirtd_qemu =
| bool_entry "vnc_sasl" | bool_entry "vnc_sasl"
| str_entry "vnc_sasl_dir" | str_entry "vnc_sasl_dir"
| str_entry "security_driver" | str_entry "security_driver"
| bool_entry "security_default_confined"
| bool_entry "security_require_confined"
| str_entry "user" | str_entry "user"
| str_entry "group" | str_entry "group"
| bool_entry "dynamic_ownership" | bool_entry "dynamic_ownership"

View File

@ -138,6 +138,14 @@
# #
# security_driver = "selinux" # 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 1.
# 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
# The user ID for QEMU processes run by the system instance. # The user ID for QEMU processes run by the system instance.
#user = "root" #user = "root"

View File

@ -75,6 +75,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
int i; int i;
/* Setup critical defaults */ /* Setup critical defaults */
driver->securityDefaultConfined = true;
driver->securityRequireConfined = false;
driver->dynamicOwnership = 1; driver->dynamicOwnership = 1;
driver->clearEmulatorCapabilities = 1; driver->clearEmulatorCapabilities = 1;
@ -195,6 +197,15 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
} }
} }
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;
p = virConfGetValue (conf, "vnc_sasl"); p = virConfGetValue (conf, "vnc_sasl");
CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG); CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG);
if (p) driver->vncSASL = p->l; if (p) driver->vncSASL = p->l;

View File

@ -115,6 +115,8 @@ struct qemud_driver {
virDomainEventStatePtr domainEventState; virDomainEventStatePtr domainEventState;
char *securityDriverName; char *securityDriverName;
bool securityDefaultConfined;
bool securityRequireConfined;
virSecurityManagerPtr securityManager; virSecurityManagerPtr securityManager;
char *saveImageFormat; char *saveImageFormat;

View File

@ -210,7 +210,10 @@ static int
qemuSecurityInit(struct qemud_driver *driver) qemuSecurityInit(struct qemud_driver *driver)
{ {
virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName, virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
driver->allowDiskFormatProbing); driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined);
if (!mgr) if (!mgr)
goto error; goto error;
@ -218,6 +221,8 @@ qemuSecurityInit(struct qemud_driver *driver)
virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user, virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
driver->group, driver->group,
driver->allowDiskFormatProbing, driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership); driver->dynamicOwnership);
if (!dac) if (!dac)
goto error; goto error;

View File

@ -36,10 +36,14 @@
struct _virSecurityManager { struct _virSecurityManager {
virSecurityDriverPtr drv; virSecurityDriverPtr drv;
bool allowDiskFormatProbing; bool allowDiskFormatProbing;
bool defaultConfined;
bool requireConfined;
}; };
static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv, static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
bool allowDiskFormatProbing) bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined)
{ {
virSecurityManagerPtr mgr; virSecurityManagerPtr mgr;
@ -50,6 +54,8 @@ static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr dr
mgr->drv = drv; mgr->drv = drv;
mgr->allowDiskFormatProbing = allowDiskFormatProbing; mgr->allowDiskFormatProbing = allowDiskFormatProbing;
mgr->defaultConfined = defaultConfined;
mgr->requireConfined = requireConfined;
if (drv->open(mgr) < 0) { if (drv->open(mgr) < 0) {
virSecurityManagerFree(mgr); virSecurityManagerFree(mgr);
@ -64,7 +70,9 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
{ {
virSecurityManagerPtr mgr = virSecurityManagerPtr mgr =
virSecurityManagerNewDriver(&virSecurityDriverStack, virSecurityManagerNewDriver(&virSecurityDriverStack,
virSecurityManagerGetAllowDiskFormatProbing(primary)); virSecurityManagerGetAllowDiskFormatProbing(primary),
virSecurityManagerGetDefaultConfined(primary),
virSecurityManagerGetRequireConfined(primary));
if (!mgr) if (!mgr)
return NULL; return NULL;
@ -78,11 +86,15 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user, virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
gid_t group, gid_t group,
bool allowDiskFormatProbing, bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined,
bool dynamicOwnership) bool dynamicOwnership)
{ {
virSecurityManagerPtr mgr = virSecurityManagerPtr mgr =
virSecurityManagerNewDriver(&virSecurityDriverDAC, virSecurityManagerNewDriver(&virSecurityDriverDAC,
allowDiskFormatProbing); allowDiskFormatProbing,
defaultConfined,
requireConfined);
if (!mgr) if (!mgr)
return NULL; return NULL;
@ -95,13 +107,18 @@ virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
} }
virSecurityManagerPtr virSecurityManagerNew(const char *name, virSecurityManagerPtr virSecurityManagerNew(const char *name,
bool allowDiskFormatProbing) bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined)
{ {
virSecurityDriverPtr drv = virSecurityDriverLookup(name); virSecurityDriverPtr drv = virSecurityDriverLookup(name);
if (!drv) if (!drv)
return NULL; return NULL;
return virSecurityManagerNewDriver(drv, allowDiskFormatProbing); return virSecurityManagerNewDriver(drv,
allowDiskFormatProbing,
defaultConfined,
requireConfined);
} }
@ -149,6 +166,16 @@ bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
return mgr->allowDiskFormatProbing; return mgr->allowDiskFormatProbing;
} }
bool virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr)
{
return mgr->defaultConfined;
}
bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
{
return mgr->requireConfined;
}
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr, int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm, virDomainDefPtr vm,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
@ -248,6 +275,20 @@ int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr, int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm) virDomainDefPtr vm)
{ {
if (vm->seclabel.type == VIR_DOMAIN_SECLABEL_DEFAULT) {
if (mgr->defaultConfined)
vm->seclabel.type = VIR_DOMAIN_SECLABEL_DYNAMIC;
else
vm->seclabel.type = VIR_DOMAIN_SECLABEL_NONE;
}
if ((vm->seclabel.type == VIR_DOMAIN_SECLABEL_NONE) &&
mgr->requireConfined) {
virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Unconfined guests are not allowed on this host"));
return -1;
}
if (mgr->drv->domainGenSecurityLabel) if (mgr->drv->domainGenSecurityLabel)
return mgr->drv->domainGenSecurityLabel(mgr, vm); return mgr->drv->domainGenSecurityLabel(mgr, vm);

View File

@ -32,7 +32,9 @@ typedef struct _virSecurityManager virSecurityManager;
typedef virSecurityManager *virSecurityManagerPtr; typedef virSecurityManager *virSecurityManagerPtr;
virSecurityManagerPtr virSecurityManagerNew(const char *name, virSecurityManagerPtr virSecurityManagerNew(const char *name,
bool allowDiskFormatProbing); bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined);
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary, virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
virSecurityManagerPtr secondary); virSecurityManagerPtr secondary);
@ -40,6 +42,8 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user, virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
gid_t group, gid_t group,
bool allowDiskFormatProbing, bool allowDiskFormatProbing,
bool defaultConfined,
bool requireConfined,
bool dynamicOwnership); bool dynamicOwnership);
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr); void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
@ -49,6 +53,8 @@ void virSecurityManagerFree(virSecurityManagerPtr mgr);
const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr); const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr);
const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr); const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr); bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
bool virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr);
bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr);
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr, int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDefPtr def,

View File

@ -171,6 +171,7 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
int c1 = 0; int c1 = 0;
int c2 = 0; int c2 = 0;
context_t ctx = NULL; context_t ctx = NULL;
const char *range;
if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) && if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
!def->seclabel.baselabel && !def->seclabel.baselabel &&
@ -201,7 +202,8 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
return rc; return rc;
} }
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) { switch (def->seclabel.type) {
case VIR_DOMAIN_SECLABEL_STATIC:
if (!(ctx = context_new(def->seclabel.label)) ) { if (!(ctx = context_new(def->seclabel.label)) ) {
virReportSystemError(errno, virReportSystemError(errno,
_("unable to allocate socket security context '%s'"), _("unable to allocate socket security context '%s'"),
@ -209,13 +211,15 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
return rc; return rc;
} }
const char *range = context_range_get(ctx); range = context_range_get(ctx);
if (!range || if (!range ||
!(mcs = strdup(range))) { !(mcs = strdup(range))) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
} else { break;
case VIR_DOMAIN_SECLABEL_DYNAMIC:
do { do {
c1 = virRandomBits(10); c1 = virRandomBits(10);
c2 = virRandomBits(10); c2 = virRandomBits(10);
@ -247,14 +251,28 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
_("cannot generate selinux context for %s"), mcs); _("cannot generate selinux context for %s"), mcs);
goto cleanup; goto cleanup;
} }
} break;
def->seclabel.imagelabel = SELinuxGenNewContext(default_image_context, mcs);
if (!def->seclabel.imagelabel) { case VIR_DOMAIN_SECLABEL_NONE:
/* no op */
break;
default:
virSecurityReportError(VIR_ERR_INTERNAL_ERROR, virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"), mcs); _("unexpected security label type '%s'"),
virDomainSeclabelTypeToString(def->seclabel.type));
goto cleanup; goto cleanup;
} }
if (!def->seclabel.norelabel) {
def->seclabel.imagelabel = SELinuxGenNewContext(default_image_context, mcs);
if (!def->seclabel.imagelabel) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"), mcs);
goto cleanup;
}
}
if (!def->seclabel.model && if (!def->seclabel.model &&
!(def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) { !(def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) {
virReportOOMError(); virReportOOMError();

View File

@ -13,7 +13,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
virSecurityManagerPtr mgr; virSecurityManagerPtr mgr;
const char *doi, *model; const char *doi, *model;
mgr = virSecurityManagerNew(NULL, false); mgr = virSecurityManagerNew(NULL, false, true, true);
if (mgr == NULL) { if (mgr == NULL) {
fprintf (stderr, "Failed to start security driver"); fprintf (stderr, "Failed to start security driver");
exit (-1); exit (-1);