This is the cherry on the top. For given device all its security labels are fetched. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virudev.c | 43 +++++++++++++++++++++++ src/util/virudev.h | 4 +++ tests/virudevtest.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0f08018..037443b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2581,6 +2581,7 @@ virTypedParamsValidate; virUdevMgrAddLabel; virUdevMgrDumpFile; virUdevMgrDumpStr; +virUdevMgrLookupLabels; virUdevMgrNew; virUdevMgrNewFromFile; virUdevMgrNewFromStr; diff --git a/src/util/virudev.c b/src/util/virudev.c index d60fbf9..9940f5f 100644 --- a/src/util/virudev.c +++ b/src/util/virudev.c @@ -300,6 +300,49 @@ virUdevMgrAddLabel(virUdevMgrPtr mgr, int +virUdevMgrLookupLabels(virUdevMgrPtr mgr, + const char *device, + virSecurityDeviceLabelDefPtr **seclabels, + size_t *nseclabels) +{ + int ret = -1; + udevSeclabelPtr list; + size_t i; + + virObjectLock(mgr); + + if (!(list = virHashLookup(mgr->labels, device))) { + *seclabels = NULL; + *nseclabels = 0; + ret = 0; + goto cleanup; + } + + if (VIR_ALLOC_N(*seclabels, list->nseclabels) < 0) + goto cleanup; + + *nseclabels = list->nseclabels; + + for (i = 0; i < list->nseclabels; i++) { + if (!((*seclabels)[i] = virSecurityDeviceLabelDefCopy(list->seclabels[i]))) + goto cleanup; + } + + ret = 0; + cleanup: + virObjectUnlock(mgr); + if (ret < 0) { + if (*seclabels) { + for (i = 0; i < *nseclabels; i++) + virSecurityDeviceLabelDefFree((*seclabels)[i]); + VIR_FREE(*seclabels); + } + } + return ret; +} + + +int virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr, const char *device) { diff --git a/src/util/virudev.h b/src/util/virudev.h index 82b2b4f..4e286bb 100644 --- a/src/util/virudev.h +++ b/src/util/virudev.h @@ -37,6 +37,10 @@ int virUdevMgrAddLabel(virUdevMgrPtr mgr, const virSecurityDeviceLabelDef *seclabel); int virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr, const char *device); +int virUdevMgrLookupLabels(virUdevMgrPtr mgr, + const char *device, + virSecurityDeviceLabelDefPtr **seclabels, + size_t *nseclabels); char *virUdevMgrDumpStr(virUdevMgrPtr mgr); diff --git a/tests/virudevtest.c b/tests/virudevtest.c index c395741..36a9077 100644 --- a/tests/virudevtest.c +++ b/tests/virudevtest.c @@ -124,6 +124,76 @@ testParse(const void *opaque) static int +testLookup(const void *opaque) +{ + const struct testUdevData *data = opaque; + virUdevMgrPtr mgr = NULL; + int ret = -1; + const char * const *tmp; + char *filename = NULL; + virSecurityDeviceLabelDefPtr *seclabels = NULL; + size_t i, nseclabels = 0; + + if (virAsprintf(&filename, "%s/virudevtestdata/%s.json", + abs_srcdir, data->file) < 0) + goto cleanup; + + if (!(mgr = virUdevMgrNewFromFile(filename))) + goto cleanup; + + tmp = data->labels; + while (*tmp) { + const char *device; + const char *model; + const char *label; + + device = *tmp; + if (!++tmp) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Invalid seclabels list"); + goto cleanup; + } + model = *tmp; + if (!++tmp) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Invalid seclabels list"); + goto cleanup; + } + label = *tmp; + tmp++; + + if (virUdevMgrLookupLabels(mgr, device, &seclabels, &nseclabels) < 0) + goto cleanup; + + for (i = 0; i < nseclabels; i++) { + virSecurityDeviceLabelDefPtr seclabel = seclabels[i]; + + if (STREQ(seclabel->model, model) && + STREQ(seclabel->label, label)) + break; + } + + if (i == nseclabels) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Label not found"); + goto cleanup; + } + + for (i = 0; i < nseclabels; i++) + virSecurityDeviceLabelDefFree(seclabels[i]); + VIR_FREE(seclabels); + nseclabels = 0; + } + + ret = 0; + cleanup: + for (i = 0; i < nseclabels; i++) + virSecurityDeviceLabelDefFree(seclabels[i]); + VIR_FREE(seclabels); + VIR_FREE(filename); + virObjectUnref(mgr); + return ret; +} + + +static int mymain(void) { int ret = 0; @@ -147,6 +217,16 @@ mymain(void) ret = -1; \ } while (0) +#define DO_TEST_LOOKUP(filename, ...) \ + do { \ + const char *labels[] = {__VA_ARGS__, NULL}; \ + struct testUdevData data = { \ + .file = filename, .labels = labels, \ + }; \ + if (virTestRun("Lookup " filename, testLookup, &data) < 0) \ + ret = -1; \ + } while (0) + DO_TEST_DUMP("empty", NULL); DO_TEST_DUMP("simple-selinux", "/dev/sda", "selinux", "someSELinuxLabel"); @@ -163,6 +243,17 @@ mymain(void) DO_TEST_PARSE("simple-dac"); DO_TEST_PARSE("complex"); + DO_TEST_LOOKUP("empty", NULL); + DO_TEST_LOOKUP("simple-selinux", + "/dev/sda", "selinux", "someSELinuxLabel"); + DO_TEST_LOOKUP("simple-dac", + "/dev/sda", "dac", "someDACLabel"); + DO_TEST_LOOKUP("complex", + "/dev/sda", "dac", "someDACLabel", + "/dev/sda", "selinux", "someSELinuxLabel", + "/dev/sdb", "dac", "otherDACLabel", + "/dev/sdb", "selinux", "otherSELinuxLabel"); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.8.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list