From fe9dffcd13e33d31da68541bc1e121656513aaf5 Mon Sep 17 00:00:00 2001 From: Zhao Jianing <18910855655@163.com> Date: Sat, 5 Sep 2026 09:02:52 +0800 Subject: [PATCH] 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> --- plugin/rewrite/reverter.go | 5 +++++ plugin/rewrite/reverter_test.go | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/plugin/rewrite/reverter.go b/plugin/rewrite/reverter.go index a99a6b076..8350b32c4 100644 --- a/plugin/rewrite/reverter.go +++ b/plugin/rewrite/reverter.go @@ -1,6 +1,8 @@ package rewrite import ( + "fmt" + "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. 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. res := res1.Copy() diff --git a/plugin/rewrite/reverter_test.go b/plugin/rewrite/reverter_test.go index b235fed3c..8800c8549 100644 --- a/plugin/rewrite/reverter_test.go +++ b/plugin/rewrite/reverter_test.go @@ -370,3 +370,22 @@ func noQuestionMsgPrinter(_ context.Context, w dns.ResponseWriter, _ *dns.Msg) ( 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") + } +}