The code that parses the schema from the URI touches the "hosts[0]" member of the storage file source structure in case the URI contains a schema. The hosts array was not yet allocated at the point in the code where the transport protocol was parsed and set. This lead to a crash of libvirtd. Fix the code by allocating the "hosts" array upfront and add a test case to verify this scenario. (Unfortunately this requires shuffling the test case numbers too). Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1156288 --- src/util/virstoragefile.c | 10 +++++----- tests/virstoragetest.c | 31 +++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 960aa23..8e9d115 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -2133,6 +2133,11 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src, goto cleanup; } + if (VIR_ALLOC(src->hosts) < 0) + goto cleanup; + + src->nhosts = 1; + if (!(scheme = virStringSplit(uri->scheme, "+", 2))) goto cleanup; @@ -2183,11 +2188,6 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src, tmp[0] = '\0'; } - if (VIR_ALLOC(src->hosts) < 0) - goto cleanup; - - src->nhosts = 1; - if (uri->port > 0) { if (virAsprintf(&src->hosts->port, "%d", uri->port) < 0) goto cleanup; diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 29f5c7a..05e48f3 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -835,6 +835,25 @@ mymain(void) (&qcow2, &nbd), EXP_PASS, (&qcow2, &nbd), ALLOW_PROBE | EXP_PASS); + /* Rewrite qcow2 to use an nbd: protocol as backend */ + virCommandFree(cmd); + cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2", + "-F", "raw", "-b", "nbd+tcp://example.org:6000/blah", + "qcow2", NULL); + if (virCommandRun(cmd, NULL) < 0) + ret = -1; + qcow2.expBackingStoreRaw = "nbd+tcp://example.org:6000/blah"; + + /* Qcow2 file with backing protocol instead of file */ + testFileData nbd2 = { + .path = "blah", + .type = VIR_STORAGE_TYPE_NETWORK, + .format = VIR_STORAGE_FILE_RAW, + }; + TEST_CHAIN(12, absqcow2, VIR_STORAGE_FILE_QCOW2, + (&qcow2, &nbd2), EXP_PASS, + (&qcow2, &nbd2), ALLOW_PROBE | EXP_PASS); + /* qed file */ testFileData qed = { .expBackingStoreRaw = absraw, @@ -848,7 +867,7 @@ mymain(void) .type = VIR_STORAGE_TYPE_FILE, .format = VIR_STORAGE_FILE_RAW, }; - TEST_CHAIN(12, absqed, VIR_STORAGE_FILE_AUTO, + TEST_CHAIN(13, absqed, VIR_STORAGE_FILE_AUTO, (&qed_as_raw), EXP_PASS, (&qed, &raw), ALLOW_PROBE | EXP_PASS); @@ -858,10 +877,10 @@ mymain(void) .type = VIR_STORAGE_TYPE_DIR, .format = VIR_STORAGE_FILE_DIR, }; - TEST_CHAIN(13, absdir, VIR_STORAGE_FILE_AUTO, + TEST_CHAIN(14, absdir, VIR_STORAGE_FILE_AUTO, (&dir), EXP_PASS, (&dir), ALLOW_PROBE | EXP_PASS); - TEST_CHAIN(14, absdir, VIR_STORAGE_FILE_DIR, + TEST_CHAIN(15, absdir, VIR_STORAGE_FILE_DIR, (&dir), EXP_PASS, (&dir), ALLOW_PROBE | EXP_PASS); @@ -900,7 +919,7 @@ mymain(void) raw.path = datadir "/sub/../sub/../raw"; raw.pathRel = "../raw"; - TEST_CHAIN(15, abslink2, VIR_STORAGE_FILE_QCOW2, + TEST_CHAIN(16, abslink2, VIR_STORAGE_FILE_QCOW2, (&link2, &link1, &raw), EXP_PASS, (&link2, &link1, &raw), ALLOW_PROBE | EXP_PASS); #endif @@ -914,7 +933,7 @@ mymain(void) qcow2.expBackingStoreRaw = "qcow2"; /* Behavior of an infinite loop chain */ - TEST_CHAIN(16, absqcow2, VIR_STORAGE_FILE_QCOW2, + TEST_CHAIN(17, absqcow2, VIR_STORAGE_FILE_QCOW2, (&qcow2), EXP_WARN, (&qcow2), ALLOW_PROBE | EXP_WARN); @@ -933,7 +952,7 @@ mymain(void) qcow2.expBackingStoreRaw = "wrap"; /* Behavior of an infinite loop chain */ - TEST_CHAIN(17, abswrap, VIR_STORAGE_FILE_QCOW2, + TEST_CHAIN(18, abswrap, VIR_STORAGE_FILE_QCOW2, (&wrap, &qcow2), EXP_WARN, (&wrap, &qcow2), ALLOW_PROBE | EXP_WARN); -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list