mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-30 17:45:23 +00:00
Support custom 'svirt_tcg_t' context for TCG based guests
The current SELinux policy only works for KVM guests, since
TCG requires the 'execmem' privilege. There is a 'virt_use_execmem'
boolean to turn this on globally, but that is unpleasant for users.
This changes libvirt to automatically use a new 'svirt_tcg_t'
context for TCG based guests. This obsoletes the previous
boolean tunable and makes things 'just work(tm)'
Since we can't assume we run with new enough policy, I also
make us log a warning message (once only) if we find the policy
lacks support. In this case we fallback to the normal label and
expect users to set the boolean tunable
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 77d3a80974
)
This commit is contained in:
parent
8a57d799ca
commit
95ea6a38bd
@ -58,6 +58,7 @@ typedef virSecuritySELinuxCallbackData *virSecuritySELinuxCallbackDataPtr;
|
|||||||
|
|
||||||
struct _virSecuritySELinuxData {
|
struct _virSecuritySELinuxData {
|
||||||
char *domain_context;
|
char *domain_context;
|
||||||
|
char *alt_domain_context;
|
||||||
char *file_context;
|
char *file_context;
|
||||||
char *content_context;
|
char *content_context;
|
||||||
virHashTablePtr mcs;
|
virHashTablePtr mcs;
|
||||||
@ -475,8 +476,23 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptr = strchrnul(data->domain_context, '\n');
|
ptr = strchrnul(data->domain_context, '\n');
|
||||||
if (ptr)
|
if (ptr && *ptr == '\n') {
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
|
ptr++;
|
||||||
|
if (*ptr != '\0') {
|
||||||
|
data->alt_domain_context = strdup(ptr);
|
||||||
|
if (!data->alt_domain_context) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
ptr = strchrnul(data->alt_domain_context, '\n');
|
||||||
|
if (ptr && *ptr == '\n')
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VIR_DEBUG("Loaded domain context '%s', alt domain context '%s'",
|
||||||
|
data->domain_context, NULLSTR(data->alt_domain_context));
|
||||||
|
|
||||||
|
|
||||||
if (virFileReadAll(selinux_virtual_image_context_path(), 2*MAX_CONTEXT, &(data->file_context)) < 0) {
|
if (virFileReadAll(selinux_virtual_image_context_path(), 2*MAX_CONTEXT, &(data->file_context)) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
@ -498,6 +514,9 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
|||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("Loaded file context '%s', content context '%s'",
|
||||||
|
data->file_context, data->content_context);
|
||||||
|
|
||||||
if (!(data->mcs = virHashCreate(10, NULL)))
|
if (!(data->mcs = virHashCreate(10, NULL)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -508,6 +527,7 @@ error:
|
|||||||
selabel_close(data->label_handle);
|
selabel_close(data->label_handle);
|
||||||
#endif
|
#endif
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
|
VIR_FREE(data->alt_domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
VIR_FREE(data->content_context);
|
VIR_FREE(data->content_context);
|
||||||
virHashFree(data->mcs);
|
virHashFree(data->mcs);
|
||||||
@ -538,6 +558,7 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
const char *range;
|
const char *range;
|
||||||
virSecurityLabelDefPtr seclabel;
|
virSecurityLabelDefPtr seclabel;
|
||||||
virSecuritySELinuxDataPtr data;
|
virSecuritySELinuxDataPtr data;
|
||||||
|
const char *baselabel;
|
||||||
|
|
||||||
if (mgr == NULL) {
|
if (mgr == NULL) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -600,10 +621,28 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
|
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
baselabel = seclabel->baselabel;
|
||||||
|
if (!baselabel) {
|
||||||
|
if (def->virtType == VIR_DOMAIN_VIRT_QEMU) {
|
||||||
|
if (data->alt_domain_context == NULL) {
|
||||||
|
static bool warned = false;
|
||||||
|
if (!warned) {
|
||||||
|
VIR_WARN("SELinux policy does not define a domain type for QEMU TCG. "
|
||||||
|
"Guest startup may be denied due to missing 'execmem' privilege "
|
||||||
|
"unless the 'virt_use_execmem' policy boolean is enabled");
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
|
baselabel = data->domain_context;
|
||||||
|
} else {
|
||||||
|
baselabel = data->alt_domain_context;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baselabel = data->domain_context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
seclabel->label =
|
seclabel->label =
|
||||||
virSecuritySELinuxGenNewContext(seclabel->baselabel ?
|
virSecuritySELinuxGenNewContext(baselabel, mcs, false);
|
||||||
seclabel->baselabel :
|
|
||||||
data->domain_context, mcs, false);
|
|
||||||
if (!seclabel->label) {
|
if (!seclabel->label) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot generate selinux context for %s"), mcs);
|
_("cannot generate selinux context for %s"), mcs);
|
||||||
@ -758,6 +797,7 @@ virSecuritySELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
|
|||||||
virHashFree(data->mcs);
|
virHashFree(data->mcs);
|
||||||
|
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
|
VIR_FREE(data->alt_domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
VIR_FREE(data->content_context);
|
VIR_FREE(data->content_context);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user