[libvirt] [PATCH v2] conf: Fix parsing of seclabels without model
Jiri Denemark
jdenemar at redhat.com
Fri Aug 31 05:34:06 UTC 2012
On Fri, Aug 31, 2012 at 12:51:51 +0800, Daniel Veillard wrote:
> On Thu, Aug 30, 2012 at 09:39:03PM -0300, Marcelo Cerri wrote:
> > With this patch libvirt tries to assign a model to a single seclabel
> > when model is missing. Libvirt will look up at host's capabilities and
> > assign the first model to seclabel.
> >
> > This patch fixes:
> >
> > 1. The problem with existing guests that have a seclabel defined in its XML.
> > 2. A XML parse error when a guest is restored.
> >
> > Signed-off-by: Marcelo Cerri <mhcerri at linux.vnet.ibm.com>
> > ---
> > src/conf/domain_conf.c | 64 +++++++++++++++++++++++++++++---------------------
> > 1 file changed, 37 insertions(+), 27 deletions(-)
> >
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 224aec5..42c3900 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -3102,22 +3102,10 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
> > def->baselabel = p;
> > }
> >
> > - /* Only parse model, if static labelling, or a base
> > - * label is set, or doing active XML
> > - */
> > - if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
> > - def->baselabel ||
> > - (!(flags & VIR_DOMAIN_XML_INACTIVE) &&
> > - def->type != VIR_DOMAIN_SECLABEL_NONE)) {
> > -
> > - p = virXPathStringLimit("string(./@model)",
> > - VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
> > - if (p == NULL && def->type != VIR_DOMAIN_SECLABEL_NONE) {
> > - virReportError(VIR_ERR_XML_ERROR,
> > - "%s", _("missing security model"));
> > - }
> > - def->model = p;
> > - }
> > + /* Always parse model */
> > + p = virXPathStringLimit("string(./@model)",
> > + VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
> > + def->model = p;
> >
> > return def;
> >
> > @@ -3129,10 +3117,12 @@ error:
> > static int
> > virSecurityLabelDefsParseXML(virDomainDefPtr def,
> > xmlXPathContextPtr ctxt,
> > + virCapsPtr caps,
> > unsigned int flags)
> > {
> > int i = 0, n;
> > xmlNodePtr *list = NULL, saved_node;
> > + virCapsHostPtr host = &caps->host;
> >
> > /* Check args and save context */
> > if (def == NULL || ctxt == NULL)
> > @@ -3159,18 +3149,38 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def,
> > ctxt->node = saved_node;
> > VIR_FREE(list);
> >
> > - /* Checking missing model information
> > - * when there is more than one seclabel */
> > - if (n > 1) {
> > - for(; n; n--) {
> > - if (def->seclabels[n - 1]->model == NULL) {
> > - virReportError(VIR_ERR_XML_ERROR, "%s",
> > - _("missing security model "
> > - "when using multiple labels"));
> > - goto error;
> > - }
> > + /* libvirt versions prior to 0.10.0 support just a single seclabel element
> > + * in guest's XML and model attribute can be suppressed if type is none or
> > + * type is dynamic, baselabel is not defined and INACTIVE flag is set.
> > + *
> > + * To avoid compatibility issues, for this specific case the first model
> > + * defined in host's capabilities is used as model for the seclabel.
> > + */
> > + if (def->nseclabels == 1 &&
> > + def->seclabels[0]->model == NULL &&
> > + def->seclabels[0]->type != VIR_DOMAIN_SECLABEL_STATIC &&
> > + def->seclabels[0]->baselabel == NULL &&
> > + (flags & VIR_DOMAIN_XML_INACTIVE) &&
> > + host->nsecModels > 0) {
> > +
> > + /* Copy model from host. */
> > + def->seclabels[0]->model = strdup(host->secModels[0].model);
...
> Fails "make check"
>
> thinkpad:~/libvirt/tests -> export VIR_TEST_DEBUG=2
> thinkpad:~/libvirt/tests -> ./qemuxml2argvtest
> ...
> 219) QEMU XML-2-ARGV seclabel-none
> ... libvir: Domain Config error : XML error: missing security model when
> using multiple labels
> FAILED
> ...
> thinkpad:~/libvirt/tests -> grep -C2 seclabel qemuxml2argvdata/qemuxml2argv-seclabel-none.xml
> <memballoon model='virtio'/>
> </devices>
> <seclabel type='none'/>
> </domain>
> thinkpad:~/libvirt/tests ->
>
> So the new code following your patch is unable to parse the construct
> <seclabel type='none'/>
This is most likely because the above condition is missing the (type is none)
part, i.e., it should be
if (def->nseclabels == 1 &&
!def->seclabels[0]->model &&
(def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE ||
(def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
!def->seclabels[0]->baselabel &&
(flags & VIR_DOMAIN_XML_INACTIVE))) &&
host->nsecModels > 0) {
...
Heh, that looks awful :-) Actually
if (def->nseclabels == 1 &&
!def->seclabels[0]->model &&
host->nsecModels > 0) {
if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE ||
(def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
!def->seclabels[0]->baselabel &&
(flags & VIR_DOMAIN_XML_INACTIVE))) {
def->seclabels[0]->model = strdup(host->secModels[0].model);
} else {
virReportError(VIR_ERR_XML_ERROR, "%s", "missing security model");
goto error;
}
}
would be a bit more readable and would also avoid confusing error message when
the model is missing but only one seclabel is used. I will try to do some
testing with this changes...
Jirka
More information about the libvir-list
mailing list