-----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 <dwa...@redhat.com>
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@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to