From cbc45525cb21988599c5eb58c31ef858e401a465 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 11 Jan 2017 17:32:46 +0100 Subject: [PATCH] qemuDomainCreateDevice: Canonicalize paths So far the decision whether /dev/* entry is created in the qemu namespace is really simple: does the path starts with "/dev/"? This can be easily fooled by providing path like the following (for any considered device like disk, rng, chardev, ..): /dev/../var/lib/libvirt/images/disk.qcow2 Therefore, before making the decision the path should be canonicalized. Signed-off-by: Michal Privoznik --- src/qemu/qemu_domain.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6e6cb844a4..1399dee0d2 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6955,28 +6955,38 @@ qemuDomainCreateDevice(const char *device, bool allow_noent) { char *devicePath = NULL; + char *canonDevicePath = NULL; struct stat sb; int ret = -1; - if (!STRPREFIX(device, DEVPREFIX)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid device: %s"), - device); + if (virFileResolveAllLinks(device, &canonDevicePath) < 0) { + if (errno == ENOENT && allow_noent) { + /* Ignore non-existent device. */ + ret = 0; + goto cleanup; + } + + virReportError(errno, _("Unable to canonicalize %s"), device); + goto cleanup; + } + + if (!STRPREFIX(canonDevicePath, DEVPREFIX)) { + ret = 0; goto cleanup; } if (virAsprintf(&devicePath, "%s/%s", - path, device + strlen(DEVPREFIX)) < 0) + path, canonDevicePath + strlen(DEVPREFIX)) < 0) goto cleanup; - if (stat(device, &sb) < 0) { + if (stat(canonDevicePath, &sb) < 0) { if (errno == ENOENT && allow_noent) { /* Ignore non-existent device. */ ret = 0; goto cleanup; } - virReportSystemError(errno, _("Unable to stat %s"), device); + virReportSystemError(errno, _("Unable to stat %s"), canonDevicePath); goto cleanup; } @@ -7005,7 +7015,7 @@ qemuDomainCreateDevice(const char *device, goto cleanup; } - if (virFileCopyACLs(device, devicePath) < 0 && + if (virFileCopyACLs(canonDevicePath, devicePath) < 0 && errno != ENOTSUP) { virReportSystemError(errno, _("Failed to copy ACLs on device %s"), @@ -7015,6 +7025,7 @@ qemuDomainCreateDevice(const char *device, ret = 0; cleanup: + VIR_FREE(canonDevicePath); VIR_FREE(devicePath); return ret; } @@ -7096,8 +7107,7 @@ qemuDomainSetupDisk(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, int ret = -1; for (next = disk->src; next; next = next->backingStore) { - if (!next->path || !virStorageSourceIsLocalStorage(next) || - !STRPREFIX(next->path, DEVPREFIX)) { + if (!next->path || !virStorageSourceIsLocalStorage(next)) { /* Not creating device. Just continue. */ continue; } @@ -7717,8 +7727,7 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver, return 0; for (next = disk->src; next; next = next->backingStore) { - if (!next->path || !virStorageSourceIsBlockLocal(disk->src) || - !STRPREFIX(next->path, DEVPREFIX)) { + if (!next->path || !virStorageSourceIsBlockLocal(disk->src)) { /* Not creating device. Just continue. */ continue; } -- GitLab