[libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

Chen Fan chen.fan.fnst at cn.fujitsu.com
Tue Oct 7 04:07:31 UTC 2014


 Signed-off-by: Chen Fan <chen.fan.fnst at cn.fujitsu.com>
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_conf.c     | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_conf.h     |  2 ++
 src/util/virsocketaddr.c | 24 +++++++++++++++++++++++
 src/util/virsocketaddr.h |  2 ++
 5 files changed, 79 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8ab1394..a104bc6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1911,6 +1911,7 @@ virSocketAddrGetIpPrefix;
 virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
+virSocketAddrIsNumericLocalhost;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index adc6caf..6b0ac5c 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -707,6 +707,15 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
     GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
     GET_VALUE_STR("migration_host", cfg->migrateHost);
+    if (cfg->migrateHost &&
+        qemuCheckLocalhost(cfg->migrateHost)) {
+        virReportError(VIR_ERR_CONF_SYNTAX,
+                       _("migration_host must not be the address of"
+                         " the local machine: %s"),
+                       cfg->migrateHost);
+        goto cleanup;
+    }
+
     GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
     GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
@@ -1371,3 +1380,44 @@ qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
 
     return qemuGetHugepagePath(&hugetlbfs[i]);
 }
+
+bool
+qemuCheckLocalhost(const char *addrStr)
+{
+    virSocketAddr addr;
+    char *hostname, *tmp;
+    bool encloseAddress = false;
+    int family;
+    bool ret = true;
+
+    if (VIR_STRDUP(hostname, addrStr) < 0)
+        return false;
+
+    tmp = hostname;
+
+    if (STRPREFIX(hostname, "[")) {
+        char *end = strchr(hostname, ']');
+        if (end) {
+            *end = '\0';
+            hostname++;
+            encloseAddress = true;
+        }
+    }
+
+    if (STRPREFIX(hostname, "localhost"))
+        goto cleanup;
+
+    family = virSocketAddrNumericFamily(hostname);
+    if ((family == AF_INET && !encloseAddress) ||
+        family == AF_INET6) {
+        if (virSocketAddrParse(&addr, hostname, family) > 0 &&
+            virSocketAddrIsNumericLocalhost(&addr)) {
+            goto cleanup;
+        }
+    }
+
+    ret = false;
+cleanup:
+    VIR_FREE(tmp);
+    return ret;
+}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index cb01fb6..c9ce53c 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -322,4 +322,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr conn,
 char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
 char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
                               size_t nhugetlbfs);
+
+bool qemuCheckLocalhost(const char *addrStr);
 #endif /* __QEMUD_CONF_H */
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 7fe7a15..6d36689 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -878,3 +878,27 @@ virSocketAddrNumericFamily(const char *address)
     freeaddrinfo(res);
     return family;
 }
+
+/**
+ * virSocketAddrIsNumericLocalhost:
+ * @address: address to check
+ *
+ * Check if passed address is a numeric 'localhost' address.
+ *
+ * Returns: true if @address is a numeric 'localhost' address,
+ *          false otherwise
+ */
+bool
+virSocketAddrIsNumericLocalhost(const virSocketAddr *addr)
+{
+    struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
+    switch (addr->data.stor.ss_family) {
+    case AF_INET:
+        return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
+                      sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
+    case AF_INET6:
+        return IN6_IS_ADDR_LOOPBACK(&addr->data.inet6.sin6_addr);
+    }
+    return false;
+
+}
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
index 35c9c1a..fa9e98b 100644
--- a/src/util/virsocketaddr.h
+++ b/src/util/virsocketaddr.h
@@ -126,4 +126,6 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
 bool virSocketAddrIsWildcard(const virSocketAddr *addr);
 
 int virSocketAddrNumericFamily(const char *address);
+
+bool virSocketAddrIsNumericLocalhost(const virSocketAddr *addr);
 #endif /* __VIR_SOCKETADDR_H__ */
-- 
1.9.3




More information about the libvir-list mailing list