]> Cypherpunks repositories - gostls13.git/commitdiff
net: ensure lookupStatic* returns copy of slice to disallow cache corruption.
authorSuharsh Sivakumar <suharshs@google.com>
Wed, 3 Feb 2016 21:22:40 +0000 (13:22 -0800)
committerMikio Hara <mikioh.mikioh@gmail.com>
Sun, 21 Feb 2016 16:36:56 +0000 (16:36 +0000)
Fixes #14212

Change-Id: I74325dfaa1fb48f4b281c2d42157b563f1e42a94
Reviewed-on: https://go-review.googlesource.com/19201
Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com>
src/net/hosts.go
src/net/hosts_test.go

index c4de1b6a9726fdfb7dc4e3baa29bbe3671589332..9c101c6ef5b307d5f7b2005066d077aeb4faad36 100644 (file)
@@ -110,7 +110,9 @@ func lookupStaticHost(host string) []string {
                lowerHost := []byte(host)
                lowerASCIIBytes(lowerHost)
                if ips, ok := hosts.byName[absDomainName(lowerHost)]; ok {
-                       return ips
+                       ipsCp := make([]string, len(ips))
+                       copy(ipsCp, ips)
+                       return ipsCp
                }
        }
        return nil
@@ -127,7 +129,9 @@ func lookupStaticAddr(addr string) []string {
        }
        if len(hosts.byAddr) != 0 {
                if hosts, ok := hosts.byAddr[addr]; ok {
-                       return hosts
+                       hostsCp := make([]string, len(hosts))
+                       copy(hostsCp, hosts)
+                       return hostsCp
                }
        }
        return nil
index 4c67bfa9824eddad56618ace0937fbaeb2c0cfff..5d6c9cfe190a3bf3f5b8aec115b9ec54b1397b57 100644 (file)
@@ -64,13 +64,17 @@ func TestLookupStaticHost(t *testing.T) {
        for _, tt := range lookupStaticHostTests {
                testHookHostsPath = tt.name
                for _, ent := range tt.ents {
-                       ins := []string{ent.in, absDomainName([]byte(ent.in)), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
-                       for _, in := range ins {
-                               addrs := lookupStaticHost(in)
-                               if !reflect.DeepEqual(addrs, ent.out) {
-                                       t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", tt.name, in, addrs, ent.out)
-                               }
-                       }
+                       testStaticHost(t, tt.name, ent)
+               }
+       }
+}
+
+func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
+       ins := []string{ent.in, absDomainName([]byte(ent.in)), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
+       for _, in := range ins {
+               addrs := lookupStaticHost(in)
+               if !reflect.DeepEqual(addrs, ent.out) {
+                       t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out)
                }
        }
 }
@@ -129,13 +133,43 @@ func TestLookupStaticAddr(t *testing.T) {
        for _, tt := range lookupStaticAddrTests {
                testHookHostsPath = tt.name
                for _, ent := range tt.ents {
-                       hosts := lookupStaticAddr(ent.in)
-                       for i := range ent.out {
-                               ent.out[i] = absDomainName([]byte(ent.out[i]))
-                       }
-                       if !reflect.DeepEqual(hosts, ent.out) {
-                               t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", tt.name, ent.in, hosts, ent.out)
-                       }
+                       testStaticAddr(t, tt.name, ent)
                }
        }
 }
+
+func testStaticAddr(t *testing.T, hostsPath string, ent staticHostEntry) {
+       hosts := lookupStaticAddr(ent.in)
+       for i := range ent.out {
+               ent.out[i] = absDomainName([]byte(ent.out[i]))
+       }
+       if !reflect.DeepEqual(hosts, ent.out) {
+               t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", hostsPath, ent.in, hosts, ent.out)
+       }
+}
+
+func TestHostCacheModification(t *testing.T) {
+       // Ensure that programs can't modify the internals of the host cache.
+       // See https://github.com/golang/go/issues/14212.
+       defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+       testHookHostsPath = "testdata/ipv4-hosts"
+       ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}
+       testStaticHost(t, testHookHostsPath, ent)
+       // Modify the addresses return by lookupStaticHost.
+       addrs := lookupStaticHost(ent.in)
+       for i := range addrs {
+               addrs[i] += "junk"
+       }
+       testStaticHost(t, testHookHostsPath, ent)
+
+       testHookHostsPath = "testdata/ipv6-hosts"
+       ent = staticHostEntry{"::1", []string{"localhost"}}
+       testStaticAddr(t, testHookHostsPath, ent)
+       // Modify the hosts return by lookupStaticAddr.
+       hosts := lookupStaticAddr(ent.in)
+       for i := range hosts {
+               hosts[i] += "junk"
+       }
+       testStaticAddr(t, testHookHostsPath, ent)
+}