-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 (Resend to the correct list) 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 One problem I had when I originally did the patch is lxcDomainGetSecurityLabel was returning the incorrect label, I needed the label of the initpid within the container not its parent process, so I changed this function to match OpenNamespaces function. One last strangeness, about half the time I run this, virsh hangs and never returns. Seems like if (conn->driver->domainGetSecurityLabel(domain, seclabel) == 0) { Gets hung up. I have attached the strace in out1.gz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iEYEARECAAYFAlEBO2EACgkQrlYvE4MpobMS5ACg3Ih4Iu0lD9BofF4iP0QXarAL jpQAoLyWWNhnnFw2TRDJsXqvrTTVujyZ =hUZ/ -----END PGP SIGNATURE-----
>From e231257274c4716ea69a630b5613b91e04ebc813 Mon Sep 17 00:00:00 2001 From: Dan Walsh <dwalsh@xxxxxxxxxx> Date: Tue, 22 Jan 2013 17:27:31 -0500 Subject: [PATCH 6/6] Set the label by default when entering a namespace, when using SELinux. Any lxc process that runs within the namespace should be running with the context of the namespace. I also added a --nolabel qualifier to virsh so you can run an unconfined_t label in the namespace and not transition. --- include/libvirt/libvirt-lxc.h | 4 ++++ src/libvirt-lxc.c | 44 ++++++++++++++++++++++++++++++++++++++++++- tools/virsh-domain.c | 8 +++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt-lxc.h b/include/libvirt/libvirt-lxc.h index f2c87fb..2fad400 100644 --- a/include/libvirt/libvirt-lxc.h +++ b/include/libvirt/libvirt-lxc.h @@ -32,6 +32,10 @@ extern "C" { # endif +typedef enum { + SECURITY_LABEL = 1 +} NamespaceFlags; + int virDomainLxcOpenNamespace(virDomainPtr domain, int **fdlist, unsigned int flags); diff --git a/src/libvirt-lxc.c b/src/libvirt-lxc.c index f580c3c..2972721 100644 --- a/src/libvirt-lxc.c +++ b/src/libvirt-lxc.c @@ -29,6 +29,9 @@ #include "virlog.h" #include "virprocess.h" #include "datatypes.h" +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#endif #define VIR_FROM_THIS VIR_FROM_NONE @@ -103,6 +106,36 @@ error: return -1; } +static int +virDomainSetDefaultSecurityLabel(virDomainPtr domain) +{ + int rc = 0; + virSecurityLabelPtr seclabel; + if (VIR_ALLOC(seclabel) < 0) + return -1; + + if (virDomainGetSecurityLabel(domain, seclabel)) + return -1; + +#ifdef WITH_SELINUX + VIR_DEBUG("setexeccon %s", seclabel->label); + rc = setexeccon(seclabel->label); + if (rc) + VIR_ERROR(_("Failed to set security context to %s"), seclabel->label); +#endif + + VIR_FREE(seclabel); + + return rc; +} + +static void +virDomainResetSecurityLabel(void) +{ +#ifdef WITH_SELINUX + (void) setexeccon(NULL); +#endif +} /** * virDomainLxcEnterNamespace: @@ -135,7 +168,12 @@ virDomainLxcEnterNamespace(virDomainPtr domain, { int i; - virCheckFlags(0, -1); + virCheckFlags(SECURITY_LABEL, -1); + + if (flags & SECURITY_LABEL) { + if (virDomainSetDefaultSecurityLabel(domain) < 0) + goto error; + } if (noldfdlist && oldfdlist) { size_t nfds; @@ -160,6 +198,10 @@ virDomainLxcEnterNamespace(virDomainPtr domain, return 0; error: + if (flags & SECURITY_LABEL) { + virDomainResetSecurityLabel(); + } + virDispatchError(domain->conn); return -1; } diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index f4b6622..5b99c94 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -7677,6 +7677,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} }; @@ -7693,6 +7694,7 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd) int nfdlist; int *fdlist; size_t i; + int flags=0; dom = vshCommandOptDomain(ctl, cmd, NULL); if (dom == NULL) @@ -7719,13 +7721,17 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd) */ if (virFork(&pid) < 0) goto cleanup; + + if (!vshCommandOptBool(cmd, "nolabel")) + flags |= SECURITY_LABEL; + if (pid == 0) { if (virDomainLxcEnterNamespace(dom, nfdlist, fdlist, NULL, NULL, - 0) < 0) + flags) < 0) _exit(255); /* Fork a second time because entering the -- 1.8.1
Attachment:
out1.gz
Description: GNU Zip compressed data
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list