plugin/rewrite: Fixes a nil pointer dereference panic in ResponseReverter.WriteMsg (#8519)

ResponseReverter.WriteMsg calls res1.Copy() without checking res1 for
nil, so any plugin further down the chain that writes a nil response
(for example a handler returning (dns.RcodeSuccess, nil) after
w.WriteMsg(nil)) panics here.

Return an error instead, mirroring the nil guard recently added to
plugin/cache's ResponseWriter.WriteMsg (#8512).

Signed-off-by: zjncs <18910855655@163.com>
This commit is contained in:
Zhao Jianing
2026-09-05 09:02:52 +08:00
committed by GitHub
parent c2e309e2e4
commit fe9dffcd13
2 changed files with 24 additions and 0 deletions

View File

@@ -1,6 +1,8 @@
package rewrite package rewrite
import ( import (
"fmt"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
@@ -84,6 +86,9 @@ func NewResponseReverter(w dns.ResponseWriter, r *dns.Msg, policy RevertPolicy)
// WriteMsg records the status code and calls the underlying ResponseWriter's WriteMsg method. // WriteMsg records the status code and calls the underlying ResponseWriter's WriteMsg method.
func (r *ResponseReverter) WriteMsg(res1 *dns.Msg) error { func (r *ResponseReverter) WriteMsg(res1 *dns.Msg) error {
if res1 == nil {
return fmt.Errorf("rewrite: response message is nil")
}
// Deep copy 'res' as to not (e.g). rewrite a message that's also stored in the cache. // Deep copy 'res' as to not (e.g). rewrite a message that's also stored in the cache.
res := res1.Copy() res := res1.Copy()

View File

@@ -370,3 +370,22 @@ func noQuestionMsgPrinter(_ context.Context, w dns.ResponseWriter, _ *dns.Msg) (
return dns.RcodeSuccess, nil return dns.RcodeSuccess, nil
} }
func TestResponseReverterWriteMsgNilResponse(t *testing.T) {
req := new(dns.Msg)
req.SetQuestion("service.example.org.", dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
rw := NewResponseReverter(rec, req, NewRevertPolicy(false, false))
defer func() {
if r := recover(); r != nil {
t.Fatalf("ResponseReverter.WriteMsg panicked on nil response: %v", r)
}
}()
err := rw.WriteMsg(nil)
if err == nil {
t.Error("Expected error when passing nil response to WriteMsg, got nil")
}
}