summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/miekg/dns/msg.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/miekg/dns/msg.go')
-rw-r--r--vendor/github.com/miekg/dns/msg.go18
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