diff options
Diffstat (limited to 'vendor/github.com/miekg/dns/msg.go')
-rw-r--r-- | vendor/github.com/miekg/dns/msg.go | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go index afce17635..975dde781 100644 --- a/vendor/github.com/miekg/dns/msg.go +++ b/vendor/github.com/miekg/dns/msg.go @@ -612,8 +612,8 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) { // If we cannot unpack the whole array, then it will return nil func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) { var r RR - // Optimistically make dst be the length that was sent - dst := make([]RR, 0, l) + // Don't pre-allocate, l may be under attacker control + var dst []RR for i := 0; i < l; i++ { off1 := off r, off, err = UnpackRR(msg, off) @@ -811,13 +811,19 @@ func (dns *Msg) Unpack(msg []byte) (err error) { dns.CheckingDisabled = (dh.Bits & _CD) != 0 dns.Rcode = int(dh.Bits & 0xF) + // If we are at the end of the message we should return *just* the + // header. This can still be useful to the caller. 9.9.9.9 sends these + // when responding with REFUSED for instance. if off == len(msg) { - return ErrTruncated + // reset sections before returning + dns.Question, dns.Answer, dns.Ns, dns.Extra = nil, nil, nil, nil + return nil } - // Optimistically use the count given to us in the header - dns.Question = make([]Question, 0, int(dh.Qdcount)) - + // Qdcount, Ancount, Nscount, Arcount can't be trusted, as they are + // attacker controlled. This means we can't use them to pre-allocate + // slices. + dns.Question = nil for i := 0; i < int(dh.Qdcount); i++ { off1 := off var q Question |