]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuDomainAttachDeviceMknod: Don't loop endlessly
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 19 Jan 2017 16:19:19 +0000 (17:19 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 7 Feb 2017 12:20:19 +0000 (13:20 +0100)
When working with symlinks it is fairly easy to get into a loop.
Don't.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_domain.c

index 86ef2ceb2c70f86bce18df8912ab88d3900b648e..89a52ab1b7cf332af63cfe926f91af05159aa0d5 100644 (file)
@@ -7735,16 +7735,24 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
 
 
 static int
-qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
-                            virDomainObjPtr vm,
-                            virDomainDeviceDefPtr devDef,
-                            const char *file)
+qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr driver,
+                                     virDomainObjPtr vm,
+                                     virDomainDeviceDefPtr devDef,
+                                     const char *file,
+                                     unsigned int ttl)
 {
     struct qemuDomainAttachDeviceMknodData data;
     int ret = -1;
     char *target = NULL;
     bool isLink;
 
+    if (!ttl) {
+        virReportSystemError(ELOOP,
+                             _("Too many levels of symbolic links: %s"),
+                             file);
+        return ret;
+    }
+
     memset(&data, 0, sizeof(data));
 
     data.driver = driver;
@@ -7822,7 +7830,8 @@ qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
     }
 
     if (isLink &&
-        qemuDomainAttachDeviceMknod(driver, vm, devDef, target) < 0)
+        qemuDomainAttachDeviceMknodRecursive(driver, vm, devDef,
+                                             target, ttl -1) < 0)
         goto cleanup;
 
     ret = 0;
@@ -7836,6 +7845,19 @@ qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
 }
 
 
+static int
+qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            virDomainDeviceDefPtr devDef,
+                            const char *file)
+{
+    long symloop_max = sysconf(_SC_SYMLOOP_MAX);
+
+    return qemuDomainAttachDeviceMknodRecursive(driver, vm, devDef,
+                                                file, symloop_max);
+}
+
+
 static int
 qemuDomainDetachDeviceUnlinkHelper(pid_t pid ATTRIBUTE_UNUSED,
                                    void *opaque)