mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-23 13:05:27 +00:00
Make virSecurityDeviceLabelDefParseXML into generic device <seclabel> parser.
This is just code motion, allowing us to reuse the same function to parse the <seclabel> from character devices too. However it also fixes a possible segfault in the original code if VIR_ALLOC_N returns an error and the cleanup code (at the error: label) tries to iterate over the unallocated array (thanks Michal Privoznik for spotting this). Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
This commit is contained in:
parent
8125113cdb
commit
db2aff6ada
@ -3258,29 +3258,30 @@ error:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse the <seclabel> from a disk or character device. */
|
||||||
static int
|
static int
|
||||||
virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
|
virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
|
||||||
|
size_t *nseclabels_rtn,
|
||||||
virSecurityLabelDefPtr *vmSeclabels,
|
virSecurityLabelDefPtr *vmSeclabels,
|
||||||
int nvmSeclabels, xmlXPathContextPtr ctxt)
|
int nvmSeclabels, xmlXPathContextPtr ctxt)
|
||||||
{
|
{
|
||||||
|
virSecurityDeviceLabelDefPtr *seclabels;
|
||||||
|
size_t nseclabels = 0;
|
||||||
int n, i, j;
|
int n, i, j;
|
||||||
xmlNodePtr *list = NULL;
|
xmlNodePtr *list = NULL;
|
||||||
virSecurityLabelDefPtr vmDef = NULL;
|
virSecurityLabelDefPtr vmDef = NULL;
|
||||||
char *model, *relabel, *label;
|
char *model, *relabel, *label;
|
||||||
|
|
||||||
if (def == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
|
if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
def->nseclabels = n;
|
if (VIR_ALLOC_N(seclabels, n) < 0) {
|
||||||
if (VIR_ALLOC_N(def->seclabels, n) < 0) {
|
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
nseclabels = n;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (VIR_ALLOC(def->seclabels[i]) < 0) {
|
if (VIR_ALLOC(seclabels[i]) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -3297,7 +3298,7 @@ virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def->seclabels[i]->model = model;
|
seclabels[i]->model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can't use overrides if top-level doesn't allow relabeling. */
|
/* Can't use overrides if top-level doesn't allow relabeling. */
|
||||||
@ -3311,9 +3312,9 @@ virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
|
|||||||
relabel = virXMLPropString(list[i], "relabel");
|
relabel = virXMLPropString(list[i], "relabel");
|
||||||
if (relabel != NULL) {
|
if (relabel != NULL) {
|
||||||
if (STREQ(relabel, "yes")) {
|
if (STREQ(relabel, "yes")) {
|
||||||
def->seclabels[i]->norelabel = false;
|
seclabels[i]->norelabel = false;
|
||||||
} else if (STREQ(relabel, "no")) {
|
} else if (STREQ(relabel, "no")) {
|
||||||
def->seclabels[i]->norelabel = true;
|
seclabels[i]->norelabel = true;
|
||||||
} else {
|
} else {
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
_("invalid security relabel value %s"),
|
_("invalid security relabel value %s"),
|
||||||
@ -3323,30 +3324,34 @@ virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
|
|||||||
}
|
}
|
||||||
VIR_FREE(relabel);
|
VIR_FREE(relabel);
|
||||||
} else {
|
} else {
|
||||||
def->seclabels[i]->norelabel = false;
|
seclabels[i]->norelabel = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxt->node = list[i];
|
ctxt->node = list[i];
|
||||||
label = virXPathStringLimit("string(./label)",
|
label = virXPathStringLimit("string(./label)",
|
||||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
def->seclabels[i]->label = label;
|
seclabels[i]->label = label;
|
||||||
|
|
||||||
if (label && def->seclabels[i]->norelabel) {
|
if (label && seclabels[i]->norelabel) {
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Cannot specify a label if relabelling is "
|
_("Cannot specify a label if relabelling is "
|
||||||
"turned off. model=%s"),
|
"turned off. model=%s"),
|
||||||
NULLSTR(def->seclabels[i]->model));
|
NULLSTR(seclabels[i]->model));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VIR_FREE(list);
|
VIR_FREE(list);
|
||||||
|
|
||||||
|
*nseclabels_rtn = nseclabels;
|
||||||
|
*seclabels_rtn = seclabels;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < nseclabels; i++) {
|
||||||
virSecurityDeviceLabelDefFree(def->seclabels[i]);
|
virSecurityDeviceLabelDefFree(seclabels[i]);
|
||||||
}
|
}
|
||||||
VIR_FREE(def->seclabels);
|
VIR_FREE(seclabels);
|
||||||
VIR_FREE(list);
|
VIR_FREE(list);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -3839,7 +3844,9 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
if (sourceNode) {
|
if (sourceNode) {
|
||||||
xmlNodePtr saved_node = ctxt->node;
|
xmlNodePtr saved_node = ctxt->node;
|
||||||
ctxt->node = sourceNode;
|
ctxt->node = sourceNode;
|
||||||
if (virSecurityDeviceLabelDefParseXML(def, vmSeclabels,
|
if (virSecurityDeviceLabelDefParseXML(&def->seclabels,
|
||||||
|
&def->nseclabels,
|
||||||
|
vmSeclabels,
|
||||||
nvmSeclabels,
|
nvmSeclabels,
|
||||||
ctxt) < 0)
|
ctxt) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user