NSEC type bitmap packing bug (#768)

* Add test case for NSEC after packing and unpacking

This is ported from:
https://gist.github.com/cesarkuroiwa/ebc2b4fb1103a7e88824865184f0c73c

* Clear msg data after pointer in packDomainName
This commit is contained in:
Tom Thorogood 2018-10-04 16:09:45 +09:30 committed by Miek Gieben
parent 008c8ca764
commit 7ca2be95a9
2 changed files with 51 additions and 0 deletions

6
msg.go
View File

@ -302,6 +302,12 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
}
// If we did compression and we find something add the pointer here
if pointer != -1 {
// Clear the msg buffer after the pointer location, otherwise
// packDataNsec writes the wrong data to msg.
tainted := msg[nameoffset:off]
for i := range tainted {
tainted[i] = 0
}
// We have two bytes (14 bits) to put the pointer in
// if msg == nil, we will never do compression
binary.BigEndian.PutUint16(msg[nameoffset:], uint16(pointer^0xC000))

View File

@ -141,3 +141,48 @@ func TestUnpackDomainName(t *testing.T) {
}
}
}
func TestPackDomainNameNSECTypeBitmap(t *testing.T) {
ownername := "some-very-long-ownername.com."
msg := &Msg{
Compress: true,
Answer: []RR{
&NS{
Hdr: RR_Header{
Name: ownername,
Rrtype: TypeNS,
Class: ClassINET,
},
Ns: "ns1.server.com.",
},
&NSEC{
Hdr: RR_Header{
Name: ownername,
Rrtype: TypeNSEC,
Class: ClassINET,
},
NextDomain: "a.com.",
TypeBitMap: []uint16{TypeNS, TypeNSEC},
},
},
}
// Pack msg and then unpack into msg2
buf, err := msg.Pack()
if err != nil {
t.Fatalf("msg.Pack failed: %v", err)
}
var msg2 Msg
if err := msg2.Unpack(buf); err != nil {
t.Fatalf("msg2.Unpack failed: %v", err)
}
if !IsDuplicate(msg.Answer[1], msg2.Answer[1]) {
t.Error("message differs after packing and unpacking")
// Print NSEC RR for both cases
t.Logf("expected: %v", msg.Answer[1])
t.Logf("got: %v", msg2.Answer[1])
}
}