aboutsummaryrefslogtreecommitdiff
path: root/src/net/dnsclient_unix_test.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2016-04-15 19:19:58 -0700
committerMatthew Dempsky <mdempsky@google.com>2016-04-22 22:16:08 +0000
commit3411d6321979b33291e3b4c6fe79d4dd41bd5fba (patch)
tree0382b4b7b3137e2c0c836279d2cec2dfc0fb812b /src/net/dnsclient_unix_test.go
parent9f1ccd647fcdb1b703c1042c90434e15aff75013 (diff)
downloadgo-3411d6321979b33291e3b4c6fe79d4dd41bd5fba.tar.gz
go-3411d6321979b33291e3b4c6fe79d4dd41bd5fba.zip
net: keep waiting for valid DNS response until timeout
Prevents denial of service attacks from bogus UDP packets. Fixes #13281. Change-Id: Ifb51b17a1b0807bfd27b144d6037431701184e7b Reviewed-on: https://go-review.googlesource.com/22126 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/net/dnsclient_unix_test.go')
-rw-r--r--src/net/dnsclient_unix_test.go83
1 files changed, 70 insertions, 13 deletions
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 761fb23f14..0b78adb853 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -567,9 +567,6 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
}
type fakeDNSConn struct {
- // last query
- qmu sync.Mutex // guards q
- q *dnsMsg
// reply handler
rh func(*dnsMsg) (*dnsMsg, error)
}
@@ -586,16 +583,76 @@ func (f *fakeDNSConn) SetDeadline(time.Time) error {
return nil
}
-func (f *fakeDNSConn) writeDNSQuery(q *dnsMsg) error {
- f.qmu.Lock()
- defer f.qmu.Unlock()
- f.q = q
- return nil
+func (f *fakeDNSConn) dnsRoundTrip(q *dnsMsg) (*dnsMsg, error) {
+ return f.rh(q)
}
-func (f *fakeDNSConn) readDNSResponse() (*dnsMsg, error) {
- f.qmu.Lock()
- q := f.q
- f.qmu.Unlock()
- return f.rh(q)
+// UDP round-tripper algorithm should ignore invalid DNS responses (issue 13281).
+func TestIgnoreDNSForgeries(t *testing.T) {
+ const TestAddr uint32 = 0x80420001
+
+ c, s := Pipe()
+ go func() {
+ b := make([]byte, 512)
+ n, err := s.Read(b)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ msg := &dnsMsg{}
+ if !msg.Unpack(b[:n]) {
+ t.Fatal("invalid DNS query")
+ }
+
+ s.Write([]byte("garbage DNS response packet"))
+
+ msg.response = true
+ msg.id++ // make invalid ID
+ b, ok := msg.Pack()
+ if !ok {
+ t.Fatal("failed to pack DNS response")
+ }
+ s.Write(b)
+
+ msg.id-- // restore original ID
+ msg.answer = []dnsRR{
+ &dnsRR_A{
+ Hdr: dnsRR_Header{
+ Name: "www.example.com.",
+ Rrtype: dnsTypeA,
+ Class: dnsClassINET,
+ Rdlength: 4,
+ },
+ A: TestAddr,
+ },
+ }
+
+ b, ok = msg.Pack()
+ if !ok {
+ t.Fatal("failed to pack DNS response")
+ }
+ s.Write(b)
+ }()
+
+ msg := &dnsMsg{
+ dnsMsgHdr: dnsMsgHdr{
+ id: 42,
+ },
+ question: []dnsQuestion{
+ {
+ Name: "www.example.com.",
+ Qtype: dnsTypeA,
+ Qclass: dnsClassINET,
+ },
+ },
+ }
+
+ resp, err := dnsRoundTripUDP(c, msg)
+ if err != nil {
+ t.Fatalf("dnsRoundTripUDP failed: %v", err)
+ }
+
+ if got := resp.answer[0].(*dnsRR_A).A; got != TestAddr {
+ t.Error("got address %v, want %v", got, TestAddr)
+ }
}