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

Michal Privoznik mprivozn at redhat.com
Fri Jan 20 09:42:48 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 | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8cbfb2d16..448583313 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -6954,9 +6954,10 @@ qemuDomainGetPreservedMounts(virQEMUDriverPtr driver,
 
 
 static int
-qemuDomainCreateDevice(const char *device,
-                       const char *path,
-                       bool allow_noent)
+qemuDomainCreateDeviceRecursive(const char *device,
+                                const char *path,
+                                bool allow_noent,
+                                unsigned int ttl)
 {
     char *devicePath = NULL;
     char *target = NULL;
@@ -6968,6 +6969,13 @@ qemuDomainCreateDevice(const char *device,
     char *tcon = NULL;
 #endif
 
+    if (!ttl) {
+        virReportSystemError(ELOOP,
+                             _("Too many levels of symbolic links: %s"),
+                             device);
+        return ret;
+    }
+
     if (lstat(device, &sb) < 0) {
         if (errno == ENOENT && allow_noent) {
             /* Ignore non-existent device. */
@@ -7057,7 +7065,8 @@ qemuDomainCreateDevice(const char *device,
             tmp = NULL;
         }
 
-        if (qemuDomainCreateDevice(target, path, allow_noent) < 0)
+        if (qemuDomainCreateDeviceRecursive(target, path,
+                                            allow_noent, ttl - 1) < 0)
             goto cleanup;
     } else {
         if (create &&
@@ -7128,6 +7137,17 @@ qemuDomainCreateDevice(const char *device,
 }
 
 
+static int
+qemuDomainCreateDevice(const char *device,
+                       const char *path,
+                       bool allow_noent)
+{
+    long symloop_max = sysconf(_SC_SYMLOOP_MAX);
+
+    return qemuDomainCreateDeviceRecursive(device, path,
+                                           allow_noent, symloop_max);
+}
+
 
 static int
 qemuDomainPopulateDevices(virQEMUDriverPtr driver,
-- 
2.11.0




More information about the libvir-list mailing list