When working with symlinks it is fairly easy to get into a loop.
Don't.
Signed-off-by: Michal Privoznik <mprivozn(a)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