]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Fix unitialized data in virSocketAddrMask
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 20 Mar 2014 10:31:37 +0000 (10:31 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 20 Mar 2014 12:15:00 +0000 (12:15 +0000)
The virSocketAddrMask method did not initialize all fields
in the sockaddr_in6 struct. In paticular the 'sin6_scope_id'
field could contain random garbage, which would in turn
affect the result of any later virSocketAddrFormat calls.
This led to ip6tables rules in the FORWARD chain which
matched on random garbage sin6_scope_id. Fortunately these
were ACCEPT rules, so the impact was merely that desired
traffic was blocked, rather than undesired traffic allowed.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/util/virsocketaddr.c
tests/sockettest.c

index 3f270e26b30de141a0ca3cd674d4ad0d3067d64d..1099eaef8088259c4ceb966ba008977ca06785c0 100644 (file)
@@ -424,6 +424,7 @@ virSocketAddrMask(const virSocketAddr *addr,
                   const virSocketAddr *netmask,
                   virSocketAddrPtr network)
 {
+    memset(network, 0, sizeof(*network));
     if (addr->data.stor.ss_family != netmask->data.stor.ss_family) {
         network->data.stor.ss_family = AF_UNSPEC;
         return -1;
index e613546b9a65b8a17e69bb7503e8dd0c8860e319..68b0536225bd806eff01be945014b1ef94b3d3f3 100644 (file)
@@ -153,6 +153,49 @@ static int testNetmaskHelper(const void *opaque)
     return testNetmask(data->addr1, data->addr2, data->netmask, data->pass);
 }
 
+
+
+static int testMaskNetwork(const char *addrstr,
+                           int prefix,
+                           const char *networkstr)
+{
+    virSocketAddr addr;
+    virSocketAddr network;
+    char *gotnet = NULL;
+
+    /* Intentionally fill with garbage */
+    memset(&network, 1, sizeof(network));
+
+    if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0)
+        return -1;
+
+    if (virSocketAddrMaskByPrefix(&addr, prefix, &network) < 0)
+        return -1;
+
+    if (!(gotnet = virSocketAddrFormat(&network)))
+        return -1;
+
+    if (STRNEQ(networkstr, gotnet)) {
+        VIR_FREE(gotnet);
+        fprintf(stderr, "Expected %s, got %s\n", networkstr, gotnet);
+        return -1;
+    }
+    VIR_FREE(gotnet);
+    return 0;
+}
+
+struct testMaskNetworkData {
+    const char *addr1;
+    int prefix;
+    const char *network;
+};
+static int testMaskNetworkHelper(const void *opaque)
+{
+    const struct testMaskNetworkData *data = opaque;
+    return testMaskNetwork(data->addr1, data->prefix, data->network);
+}
+
+
 static int testWildcard(const char *addrstr,
                         bool pass)
 {
@@ -255,6 +298,14 @@ mymain(void)
             ret = -1;                                                   \
     } while (0)
 
+#define DO_TEST_MASK_NETWORK(addr1, prefix, network)                    \
+    do {                                                                \
+        struct testMaskNetworkData data = { addr1, prefix, network };   \
+        if (virtTestRun("Test mask network " addr1 " / " #prefix " == " network, \
+                        testMaskNetworkHelper, &data) < 0)              \
+            ret = -1;                                                   \
+    } while (0)
+
 #define DO_TEST_WILDCARD(addr, pass)                                    \
     do {                                                                \
         struct testWildcardData data = { addr, pass};                   \
@@ -324,6 +375,8 @@ mymain(void)
     DO_TEST_NETMASK("2000::1:1", "9000::1:1",
                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
 
+    DO_TEST_MASK_NETWORK("2001:db8:ca2:2::1", 64, "2001:db8:ca2:2::");
+
     DO_TEST_WILDCARD("0.0.0.0", true);
     DO_TEST_WILDCARD("::", true);
     DO_TEST_WILDCARD("0", true);