-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 03/12/2013 03:06 PM, Eric Blake wrote:
> On 03/12/2013 11:28 AM, Daniel P. Berrange wrote:
>> From: "Daniel P. Berrange" <[email protected]>
>>
>> Add a new virDomainLxcEnterSecurityLabel() function as a counterpart to
>> virDomainLxcEnterNamespaces(), which can change the current calling
>> process to have a new security context. This call runs client side, not
>> in libvirtd so we can't use the security driver infrastructure.
>>
>> When entering a namespace, the process spawned from virsh will default to
>> running with the security label of virsh. The actual desired behaviour is
>> to run with the security label of the container most of the time. So this
>> changes virsh lxc-enter-namespace command to invoke the
>> virDomainLxcEnterSecurityLabel method.
>>
>
>> include/libvirt/libvirt-lxc.h | 4 ++ python/generator.py | 1
>> + src/libvirt-lxc.c | 96
>> +++++++++++++++++++++++++++++++++++++++++++ tools/virsh-domain.c
>> | 32 +++++++++++++++ 4 files changed, 133 insertions(+)
>
> Missing an entry in src/libvirt_lxc.syms to actually expose the new
> function in the .so.
>
>> +++ 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
>
> Will fail 'make syntax-check' if cppi is installed.
>
>> @@ -8029,12 +8036,35 @@ cmdLxcEnterNamespace(vshControl *ctl, const
>> vshCmd *cmd) if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) <
>> 0) goto cleanup;
>>
>> + if (setlabel) { + fprintf(stderr, "Getr sec\n");
>
> Spurious debug message?
>
> ACK with those things addressed.
>
Here is my current patch for this, with a fix for the syms file.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iEYEARECAAYFAlE/hLoACgkQrlYvE4MpobPImgCggDyVpwbhsy4lMd2nZmTGavCF
qkIAn0gJT1xc2487N8HP081M1ydC02rn
=VTUO
-----END PGP SIGNATURE-----
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);
+
# ifdef __cplusplus
}
# endif
diff --git a/python/generator.py b/python/generator.py
index 8236bd2..308b776 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -557,6 +557,7 @@ skip_function = (
lxc_skip_function = (
"virDomainLxcEnterNamespace",
+ "virDomainLxcGetSecurityLabel",
)
qemu_skip_function = (
#"virDomainQemuAttach",
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;
+}
+
+/**
* virDomainLxcOpenNamespace:
* @domain: a domain object
* @fdlist: pointer to an array to be filled with FDs
diff --git a/src/libvirt_lxc.syms b/src/libvirt_lxc.syms
index b5be18b..3ef4eb8 100644
--- a/src/libvirt_lxc.syms
+++ b/src/libvirt_lxc.syms
@@ -14,4 +14,5 @@ LIBVIRT_LXC_1.0.2 {
global:
virDomainLxcEnterNamespace;
virDomainLxcOpenNamespace;
+ virDomainLxcGetSecurityLabel;
};
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index f136df2..89f87f2 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;
+ }
if (virSecurityManagerGetProcessLabel(driver->securityManager,
- vm->def, vm->pid, seclabel) < 0) {
+ vm->def, priv->initpid, seclabel) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to get security label"));
goto cleanup;
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c272688..b6203e2 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
+
/* libxml2 in RHEL4 has this symbol in the binary but it
* is commented out in the header, despite apparently
* working fine. This hacks around that header problem
@@ -8003,6 +8007,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}
};
@@ -8011,6 +8016,7 @@ static bool
cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom = NULL;
+ virSecurityLabelPtr seclabel;
bool ret = false;
const vshCmdOpt *opt = NULL;
char **cmdargv = NULL;
@@ -8019,6 +8025,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)
@@ -8040,12 +8047,33 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0)
goto cleanup;
+#ifdef WITH_SELINUX
+ if ((is_selinux_enabled() > 0) &&
+ (! vshCommandOptBool(cmd, "nolabel"))) {
+ if (VIR_ALLOC(seclabel) < 0)
+ goto cleanup;
+ label = true;
+ if (virDomainGetSecurityLabel(dom, seclabel) < 0)
+ goto cleanup;
+ }
+#endif
+
/* Fork once because we don't want to affect
* virsh's namespace itself
*/
if (virFork(&pid) < 0)
goto cleanup;
if (pid == 0) {
+#ifdef WITH_SELINUX
+ if (label) {
+ vshDebug(ctl, VSH_ERR_INFO, "setexeccon %s", seclabel->label);
+ ret = setexeccon(seclabel->label);
+ if (ret < 0) {
+ vshError(ctl, _("Failed to set security context to %s"), seclabel->label);
+ _exit(255);
+ }
+ }
+#endif
if (virDomainLxcEnterNamespace(dom,
nfdlist,
fdlist,
@@ -8078,6 +8106,8 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
ret = true;
cleanup:
+ if (label)
+ VIR_FREE(seclabel);
if (dom)
virDomainFree(dom);
VIR_FREE(cmdargv);
--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list