diff -rup libvirt-0.7.7/src/conf/storage_conf.c new/src/conf/storage_conf.c --- libvirt-0.7.7/src/conf/storage_conf.c 2010-03-05 09:46:29.000000000 -0500 +++ new/src/conf/storage_conf.c 2010-06-17 12:28:44.319588000 -0400 @@ -601,6 +601,7 @@ virStoragePoolDefParseXML(xmlXPathContex xmlNodePtr source_node; char *type = NULL; char *uuid = NULL; + char *tmppath; if (VIR_ALLOC(ret) < 0) { virReportOOMError(); @@ -698,11 +699,16 @@ virStoragePoolDefParseXML(xmlXPathContex } } - if ((ret->target.path = virXPathString("string(./target/path)", ctxt)) == NULL) { + if ((tmppath = virXPathString("string(./target/path)", ctxt)) == NULL) { virStorageReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage pool target path")); goto cleanup; } + ret->target.path = virFileSanitizePath(tmppath); + VIR_FREE(tmppath); + if (!ret->target.path) + goto cleanup; + if (virStorageDefParsePerms(ctxt, &ret->target.perms, "./target/permissions", 0700) < 0) diff -rup libvirt-0.7.7/src/libvirt_private.syms new/src/libvirt_private.syms --- libvirt-0.7.7/src/libvirt_private.syms 2010-03-05 10:45:23.000000000 -0500 +++ new/src/libvirt_private.syms 2010-06-17 12:28:44.334585000 -0400 @@ -582,6 +582,7 @@ virFileReadLimFD; virFilePid; virFileReadPid; virFileLinkPointsTo; +virFileSanitizePath; virParseNumber; virAsprintf; virRun; diff -rup libvirt-0.7.7/src/storage/storage_driver.c new/src/storage/storage_driver.c --- libvirt-0.7.7/src/storage/storage_driver.c 2010-03-05 09:46:29.000000000 -0500 +++ new/src/storage/storage_driver.c 2010-06-17 12:28:44.346586000 -0400 @@ -1200,6 +1200,11 @@ storageVolumeLookupByPath(virConnectPtr virStorageDriverStatePtr driver = conn->storagePrivateData; unsigned int i; virStorageVolPtr ret = NULL; + char *cleanpath; + + cleanpath = virFileSanitizePath(path); + if (!cleanpath) + return NULL; storageDriverLock(driver); for (i = 0 ; i < driver->pools.count && !ret ; i++) { @@ -1209,7 +1214,7 @@ storageVolumeLookupByPath(virConnectPtr const char *stable_path; stable_path = virStorageBackendStablePath(driver->pools.objs[i], - path); + cleanpath); /* * virStorageBackendStablePath already does * virStorageReportError if it fails; we just need to keep @@ -1238,6 +1243,7 @@ storageVolumeLookupByPath(virConnectPtr "%s", _("no storage vol with matching path")); cleanup: + VIR_FREE(cleanpath); storageDriverUnlock(driver); return ret; } diff -rup libvirt-0.7.7/src/util/util.c new/src/util/util.c --- libvirt-0.7.7/src/util/util.c 2010-03-03 05:48:25.000000000 -0500 +++ new/src/util/util.c 2010-06-17 12:28:44.357588000 -0400 @@ -1867,6 +1867,55 @@ int virFileAbsPath(const char *path, cha return 0; } +/* Remove spurious / characters from a path. The result must be freed */ +char * +virFileSanitizePath(const char *path) +{ + const char *cur = path; + char *cleanpath; + int idx = 0; + + cleanpath = strdup(path); + if (!cleanpath) { + virReportOOMError(); + return NULL; + } + + /* Need to sanitize: + * // -> // + * /// -> / + * /../foo -> /../foo + * /foo///bar/ -> /foo/bar + */ + + /* Starting with // is valid posix, but ///foo == /foo */ + if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') { + idx = 2; + cur += 2; + } + + /* Sanitize path in place */ + while (*cur != '\0') { + if (*cur != '/') { + cleanpath[idx++] = *cur++; + continue; + } + + /* Skip all extra / */ + while (*++cur == '/') + continue; + + /* Don't add a trailing / */ + if (idx != 0 && *cur == '\0') + break; + + cleanpath[idx++] = '/'; + } + cleanpath[idx] = '\0'; + + return cleanpath; +} + /* Like strtol, but produce an "int" result, and check more carefully. Return 0 upon success; return -1 to indicate failure. When END_PTR is NULL, the byte after the final valid digit must be NUL. diff -rup libvirt-0.7.7/src/util/util.h new/src/util/util.h --- libvirt-0.7.7/src/util/util.h 2010-02-19 12:14:07.000000000 -0500 +++ new/src/util/util.h 2010-06-17 12:28:44.364585000 -0400 @@ -109,6 +109,8 @@ char *virFindFileInPath(const char *file int virFileExists(const char *path); +char *virFileSanitizePath(const char *path); + enum { VIR_FILE_OP_NONE = 0, VIR_FILE_OP_AS_UID = (1 << 0), diff -rup libvirt-0.7.7/tests/storagepoolxml2xmlin/pool-dir.xml new/tests/storagepoolxml2xmlin/pool-dir.xml --- libvirt-0.7.7/tests/storagepoolxml2xmlin/pool-dir.xml 2009-12-22 04:37:57.000000000 -0500 +++ new/tests/storagepoolxml2xmlin/pool-dir.xml 2010-06-17 12:28:44.367585000 -0400 @@ -7,7 +7,7 @@ - /var/lib/libvirt/images + ///var/////lib/libvirt/images// 0700 0