Fix panic when stripping multiple EDNS0 padding options (#199)

This commit is contained in:
Frank Olbricht
2021-12-26 10:56:59 -07:00
committed by GitHub
parent 195ca70171
commit 4ca5495afc
2 changed files with 63 additions and 6 deletions

View File

@@ -12,7 +12,7 @@ const ResponsePaddingBlockSize = 468
var respPadBuf [ResponsePaddingBlockSize]byte
var queryPadBuf [QueryPaddingBlockSize]byte
// Add padding to an answer before it's sent back over DoH or DoT accodring to rfc8467.
// Add padding to an answer before it's sent back over DoH or DoT according to rfc8467.
// Don't call this for un-encrypted responses as they should not be padded.
func padAnswer(q, a *dns.Msg) {
edns0q := q.IsEdns0()
@@ -87,16 +87,17 @@ func padQuery(q *dns.Msg) {
}
// Remove padding from a query or response. Typically needed when sending a response that was received
// via TLS over a plan connection.
// via TLS over a plain connection.
func stripPadding(m *dns.Msg) {
edns0 := m.IsEdns0()
if edns0 == nil { // Nothing to do here
return
}
for i, opt := range edns0.Option {
if opt.Option() == dns.EDNS0PADDING {
edns0.Option = append(edns0.Option[:i], edns0.Option[i+1:]...)
var newOpt []dns.EDNS0
for _, opt := range edns0.Option {
if opt.Option() != dns.EDNS0PADDING {
newOpt = append(newOpt, opt)
}
}
edns0.Option = newOpt
}

View File

@@ -64,3 +64,59 @@ func TestStripPadding(t *testing.T) {
len2 := q.Len()
require.Equal(t, len1, len2, "padding not stripped off correctly")
}
func TestStripPaddingMulti(t *testing.T) {
q := new(dns.Msg)
q.SetQuestion("google.com.", dns.TypeA)
q.SetEdns0(4096, false)
edns0 := q.IsEdns0()
tests := []struct {
opts []dns.EDNS0
lenAfterStrip int
}{
{
opts: nil,
lenAfterStrip: 0,
},
{
opts: []dns.EDNS0{},
lenAfterStrip: 0,
},
{
opts: []dns.EDNS0{
&dns.EDNS0_PADDING{},
},
lenAfterStrip: 0,
},
{
opts: []dns.EDNS0{
&dns.EDNS0_PADDING{},
&dns.EDNS0_PADDING{},
},
lenAfterStrip: 0,
},
{
opts: []dns.EDNS0{
&dns.EDNS0_PADDING{},
&dns.EDNS0_PADDING{},
&dns.EDNS0_NSID{},
},
lenAfterStrip: 1,
},
{
opts: []dns.EDNS0{
&dns.EDNS0_NSID{},
&dns.EDNS0_PADDING{},
&dns.EDNS0_PADDING{},
},
lenAfterStrip: 1,
},
}
for _, test := range tests {
edns0.Option = test.opts
stripPadding(q)
require.Len(t, edns0.Option, test.lenAfterStrip)
}
}