[libvirt] This patch adds the label to lxc-enter-namespace

Daniel P. Berrange berrange at redhat.com
Fri Feb 1 16:20:59 UTC 2013


On Fri, Jan 25, 2013 at 02:39:25PM -0500, Daniel J Walsh wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> (2nd pass)
> 
> 
> lxc-enter-namespace  allows a process from outside a container to start a
> process inside a container.  One problem with the current code is the process
> running within the container would run with the label of the process that
> created it.
> 
> For example if the admin process is running as unconfined_t and executes the
> following command
> 
> 
> # virsh -c lxc:/// lxc-enter-namespace --nolabel dan -- /bin/ps -eZ
> LABEL                             PID TTY          TIME CMD
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 1 pts/0 00:00:00 systemd
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 3 pts/1 00:00:00 sh
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 24 ? 00:00:00 systemd-journal
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 29 ? 00:00:00 dhclient
> staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 47 ? 00:00:00 ps
> 
> Note the ps command is running as unconfined_t,  After this patch,
> 
> 
> virsh -c lxc:/// lxc-enter-namespace dan -- /bin/ps -eZ
> LABEL                             PID TTY          TIME CMD
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 1 pts/0 00:00:00 systemd
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 3 pts/1 00:00:00 sh
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 24 ? 00:00:00 systemd-journal
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 32 ? 00:00:00 dhclient
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 38 ? 00:00:00 ps
> 
> I also add a --nolabel command to virsh, which can go back to the original
> behaviour.
> 
> virsh -c lxc:/// lxc-enter-namespace --nolabel dan -- /bin/ps -eZ
> LABEL                             PID TTY          TIME CMD
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 1 pts/0 00:00:00 systemd
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 3 pts/1 00:00:00 sh
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 24 ? 00:00:00 systemd-journal
> system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 32 ? 00:00:00 dhclient
> staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 37 ? 00:00:00 ps


> diff --git a/include/libvirt/libvirt-lxc.h b/include/libvirt/libvirt-lxc.h
> index f2c87fb..257637b 100644
> --- a/include/libvirt/libvirt-lxc.h
> +++ b/include/libvirt/libvirt-lxc.h
> @@ -43,6 +43,9 @@ int virDomainLxcEnterNamespace(virDomainPtr domain,
>                                 int **oldfdlist,
>                                 unsigned int flags);
>  
> +int virDomainLxcGetSecurityLabel(virDomainPtr domain,
> +                                 virSecurityLabelPtr seclabel);
> +

I'm not sure why you're adding this method - it is identical
to the existing virDomainGetSecurityLabel() method. Just
remove this.

>  # ifdef __cplusplus
>  }
>  # endif
> diff --git a/python/generator.py b/python/generator.py
> index f853d77..f98818e 100755
> --- a/python/generator.py
> +++ b/python/generator.py
> @@ -551,6 +551,7 @@ skip_function = (
>  
>  lxc_skip_function = (
>    "virDomainLxcEnterNamespace",
> +  "virDomainLxcGetSecurityLabel",

And remove this.

> diff --git a/src/libvirt-lxc.c b/src/libvirt-lxc.c
> index f580c3c..a4aff59 100644
> --- a/src/libvirt-lxc.c
> +++ b/src/libvirt-lxc.c
> @@ -41,6 +41,57 @@
>                           __LINE__, info)
>  
>  /**
> + * virDomainLxcGetSecurityLabel:
> + * @domain: a domain object
> + * @seclabel: pointer to a virSecurityLabel structure
> + *
> + * This API is LXC specific, so it will only work with hypervisor
> + * connections to the LXC driver.
> + *
> + * Get the security label associated with the container @domain.
> + *
> + * Returns 0 on success, or -1 on error
> + */
> +int
> +virDomainLxcGetSecurityLabel(virDomainPtr domain,
> +				 virSecurityLabelPtr seclabel)
> +{
> +    virConnectPtr conn;
> +
> +    VIR_DEBUG("domain=%p", domain);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
> +	virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
> +	virDispatchError(NULL);
> +	return -1;
> +    }
> +
> +    conn = domain->conn;
> +
> +    if (conn->flags & VIR_CONNECT_RO) {
> +	virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
> +	goto error;
> +    }
> +
> +    if (conn->driver->domainGetSecurityLabel) {
> +
> +	if (conn->driver->domainGetSecurityLabel(domain,
> +						 seclabel) < 0)
> +	    goto error;
> +
> +	return 0;
> +    }
> +
> +    virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}

And remove this.

> diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
> index 1fe8039..fd60712 100644
> --- a/src/lxc/lxc_driver.c
> +++ b/src/lxc/lxc_driver.c
> @@ -1125,6 +1125,7 @@ static int lxcDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr secla
>  {
>      virLXCDriverPtr driver = dom->conn->privateData;
>      virDomainObjPtr vm;
> +    virLXCDomainObjPrivatePtr priv;
>      int ret = -1;
>  
>      lxcDriverLock(driver);
> @@ -1162,8 +1163,14 @@ static int lxcDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr secla
>       *   LXC monitor hasn't seen SIGHUP/ERR on poll().
>       */
>      if (virDomainObjIsActive(vm)) {
> +	priv = vm->privateData;
> +	if (!priv->initpid) {
> +	    virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +			   _("Init pid is not yet available"));
> +	    goto cleanup;
> +	}

Identation has gone a bit screwy here.

>          if (virSecurityManagerGetProcessLabel(driver->securityManager,
> -                                              vm->def, vm->pid, seclabel) < 0) {
> +                                              vm->def, priv->initpid, seclabel) < 0) {

Yep, this makes sense

> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
> index 026dac1..c53f817 100644
> --- a/tools/virsh-domain.c
> +++ b/tools/virsh-domain.c
> @@ -56,6 +56,10 @@
>  #include "virtypedparam.h"
>  #include "virxml.h"
>  
> +#ifdef WITH_SELINUX
> +#include <selinux/selinux.h>
> +#endif

You need to use '# include' rather than "#include" in order
to get 'make syntax-check' pass

> @@ -7678,6 +7682,7 @@ static const vshCmdInfo info_lxc_enter_namespace[] = {
>  
>  static const vshCmdOptDef opts_lxc_enter_namespace[] = {
>      {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
> +    {"nolabel", VSH_OT_BOOL, 0, N_("Do Not Change Process Label ")},
>      {"cmd", VSH_OT_ARGV, VSH_OFLAG_REQ, N_("namespace")},
>      {NULL, 0, 0, NULL}
>  };
> @@ -7686,6 +7691,7 @@ static bool
>  cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
>  {
>      virDomainPtr dom = NULL;
> +    virSecurityLabelPtr seclabel;

If you declare this as 'virSecurityLabel seclabel'...

>      bool ret = false;
>      const vshCmdOpt *opt = NULL;
>      char **cmdargv = NULL;
> @@ -7694,6 +7700,7 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
>      int nfdlist;
>      int *fdlist;
>      size_t i;
> +    int label = false;
>  
>      dom = vshCommandOptDomain(ctl, cmd, NULL);
>      if (dom == NULL)
> @@ -7715,12 +7722,30 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
>      if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0)
>          goto cleanup;
>  
> +    if (! vshCommandOptBool(cmd, "nolabel")) {
> +        if (VIR_ALLOC(seclabel) < 0)
> +            goto cleanup;

...this allocation can be removed.

> +        label = true;
> +        if (virDomainLxcGetSecurityLabel(dom, seclabel) < 0)

Just replace this call with virDomainGetSecurityLabel()

>  cleanup:
> +    if (label)
> +        VIR_FREE(seclabel);

And then this can go too


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list