[libvirt] [PATCH] Support custom 'svirt_tcg_t' context for TCG based guests

Cole Robinson crobinso at redhat.com
Sun Dec 16 19:34:12 UTC 2012


On 12/12/2012 06:49 AM, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> 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 at redhat.com>
> ---
>  src/security/security_selinux.c | 48 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 44 insertions(+), 4 deletions(-)
> 
> diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
> index 5409e32..82cbc80 100644
> --- a/src/security/security_selinux.c
> +++ b/src/security/security_selinux.c
> @@ -58,6 +58,7 @@ typedef virSecuritySELinuxCallbackData *virSecuritySELinuxCallbackDataPtr;
>  
>  struct _virSecuritySELinuxData {
>      char *domain_context;
> +    char *alt_domain_context;
>      char *file_context;
>      char *content_context;
>      virHashTablePtr mcs;
> @@ -446,8 +447,23 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
>      }
>  
>      ptr = strchrnul(data->domain_context, '\n');
> -    if (ptr)
> +    if (ptr && *ptr == '\n') {
>          *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) {
>          virReportSystemError(errno,
> @@ -469,6 +485,9 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
>              *ptr = '\0';
>      }
>  
> +    VIR_DEBUG("Loaded file context '%s', content context '%s'",
> +              data->file_context, data->content_context);
> +
>      if (!(data->mcs = virHashCreate(10, NULL)))
>          goto error;
>  
> @@ -476,6 +495,7 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
>  
>  error:
>      VIR_FREE(data->domain_context);
> +    VIR_FREE(data->alt_domain_context);
>      VIR_FREE(data->file_context);
>      VIR_FREE(data->content_context);
>      virHashFree(data->mcs);
> @@ -506,6 +526,7 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
>      const char *range;
>      virSecurityLabelDefPtr seclabel;
>      virSecuritySELinuxDataPtr data;
> +    const char *baselabel;
>  
>      if (mgr == NULL) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -568,10 +589,28 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
>          if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
>              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 =
> -            virSecuritySELinuxGenNewContext(seclabel->baselabel ?
> -                                 seclabel->baselabel :
> -                                 data->domain_context, mcs, false);
> +            virSecuritySELinuxGenNewContext(baselabel, mcs, false);
>          if (!seclabel->label)  {
>              virReportError(VIR_ERR_INTERNAL_ERROR,
>                             _("cannot generate selinux context for %s"), mcs);
> @@ -722,6 +761,7 @@ virSecuritySELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
>      virHashFree(data->mcs);
>  
>      VIR_FREE(data->domain_context);
> +    VIR_FREE(data->alt_domain_context);
>      VIR_FREE(data->file_context);
>      VIR_FREE(data->content_context);
>  
> 

ACK. Though to get it to work I had to tweak the domain policy file, since F18
selinux-policy seemed to have lost that change:

https://bugzilla.redhat.com/show_bug.cgi?id=885836#c4

- Cole




More information about the libvir-list mailing list