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