[libvirt] [PATCH 10/10] qemuDomainAttachDeviceMknod: Don't loop endlessly

Michal Privoznik mprivozn at redhat.com
Fri Jan 20 09:42:50 UTC 2017


When working with symlinks it is fairly easy to get into a loop.
Don't.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_domain.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index bcfb2446f..db01bd230 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7690,16 +7690,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;
@@ -7777,7 +7785,8 @@ qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
     }
 
     if (isLink &&
-        qemuDomainAttachDeviceMknod(driver, vm, devDef, target) < 0)
+        qemuDomainAttachDeviceMknodRecursive(driver, vm, devDef,
+                                             target, ttl -1) < 0)
         goto cleanup;
 
     ret = 0;
@@ -7791,6 +7800,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)
-- 
2.11.0




More information about the libvir-list mailing list