From 822d2c7ffac4bc341a49cade806e3407b539e2ad Mon Sep 17 00:00:00 2001 From: zhaosai Date: Sat, 11 May 2024 16:46:13 +0800 Subject: [PATCH] fix CVE-2024-24788 --- ...s-client-check-skip-additional-error.patch | 126 ++++++++++++++++++ ...-client-avoid-potential-endless-loop.patch | 35 +++++ golang.spec | 7 +- 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 backport-0007-Backport-net-dns-client-check-skip-additional-error.patch create mode 100644 backport-0008-Backport-net-dns-client-avoid-potential-endless-loop.patch diff --git a/backport-0007-Backport-net-dns-client-check-skip-additional-error.patch b/backport-0007-Backport-net-dns-client-check-skip-additional-error.patch new file mode 100644 index 0000000..5c8dc41 --- /dev/null +++ b/backport-0007-Backport-net-dns-client-check-skip-additional-error.patch @@ -0,0 +1,126 @@ +From 865760373194e358fefa4d1e45ebdf2141b77b59 Mon Sep 17 00:00:00 2001 +From: Mateusz Poliwczak +Date: Tue, 1 Aug 2023 18:02:54 +0000 +Subject: [PATCH] net: use the extended RCode from EDNS(0) OPT resources + +For a while now we support EDNS, but the current +implementation only sends the OPT resource and doesn't +do anything with the response OPT resource. + +For reference the miekg/dns updates the RCode in the +header when there is a OPT resource: +https://github.com/miekg/dns/blob/48f38ebef989eedc6b57f1869ae849ccc8f5fe29/msg.go#L868-L872 + +Change-Id: I0a7146aed3e50654f340a3925f48612561cb85f4 +GitHub-Last-Rev: adc304167e0540cb1f066f07a249d67fad89182e +GitHub-Pull-Request: golang/go#61695 +Reviewed-on: https://go-review.googlesource.com/c/go/+/514835 +TryBot-Result: Gopher Robot +Reviewed-by: David Chase +Run-TryBot: Ian Lance Taylor +Reviewed-by: Ian Lance Taylor +Auto-Submit: Ian Lance Taylor +--- + src/net/dnsclient_unix.go | 27 +++++++++++++++++++++++---- + src/net/dnsclient_unix_test.go | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 4 deletions(-) + +diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go +index dab5144e5d7ae..ed32ba028069c 100644 +--- a/src/net/dnsclient_unix.go ++++ b/src/net/dnsclient_unix.go +@@ -205,7 +205,9 @@ func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Que + + // checkHeader performs basic sanity checks on the header. + func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error { +- if h.RCode == dnsmessage.RCodeNameError { ++ rcode := extractExtendedRCode(*p, h) ++ ++ if rcode == dnsmessage.RCodeNameError { + return errNoSuchHost + } + +@@ -216,17 +218,17 @@ func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error { + + // libresolv continues to the next server when it receives + // an invalid referral response. See golang.org/issue/15434. +- if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone { ++ if rcode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone { + return errLameReferral + } + +- if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError { ++ if rcode != dnsmessage.RCodeSuccess && rcode != dnsmessage.RCodeNameError { + // None of the error codes make sense + // for the query we sent. If we didn't get + // a name error and we didn't get success, + // the server is behaving incorrectly or + // having temporary trouble. +- if h.RCode == dnsmessage.RCodeServerFailure { ++ if rcode == dnsmessage.RCodeServerFailure { + return errServerTemporarilyMisbehaving + } + return errServerMisbehaving +@@ -253,6 +255,23 @@ func skipToAnswer(p *dnsmessage.Parser, qtype dnsmessage.Type) error { + } + } + ++// extractExtendedRCode extracts the extended RCode from the OPT resource (EDNS(0)) ++// If an OPT record is not found, the RCode from the hdr is returned. ++func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) dnsmessage.RCode { ++ p.SkipAllAnswers() ++ p.SkipAllAuthorities() ++ for { ++ ahdr, err := p.AdditionalHeader() ++ if err != nil { ++ return hdr.RCode ++ } ++ if ahdr.Type == dnsmessage.TypeOPT { ++ return ahdr.ExtendedRCode(hdr.RCode) ++ } ++ p.SkipAdditional() ++ } ++} ++ + // Do a lookup for a single name, which must be rooted + // (otherwise answer will not find the answers). + func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, error) { +diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go +index 8d435a557f26f..9ae68f9a99206 100644 +--- a/src/net/dnsclient_unix_test.go ++++ b/src/net/dnsclient_unix_test.go +@@ -2598,3 +2598,34 @@ func TestLookupOrderFilesNoSuchHost(t *testing.T) { + } + } + } ++ ++func TestExtendedRCode(t *testing.T) { ++ fake := fakeDNSServer{ ++ rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { ++ fraudSuccessCode := dnsmessage.RCodeSuccess | 1<<10 ++ ++ var edns0Hdr dnsmessage.ResourceHeader ++ edns0Hdr.SetEDNS0(maxDNSPacketSize, fraudSuccessCode, false) ++ ++ return dnsmessage.Message{ ++ Header: dnsmessage.Header{ ++ ID: q.Header.ID, ++ Response: true, ++ RCode: fraudSuccessCode, ++ }, ++ Questions: []dnsmessage.Question{q.Questions[0]}, ++ Additionals: []dnsmessage.Resource{{ ++ Header: edns0Hdr, ++ Body: &dnsmessage.OPTResource{}, ++ }}, ++ }, nil ++ }, ++ } ++ ++ r := &Resolver{PreferGo: true, Dial: fake.DialContext} ++ _, _, err := r.tryOneName(context.Background(), getSystemDNSConfig(), "go.dev.", dnsmessage.TypeA) ++ var dnsErr *DNSError ++ if !(errors.As(err, &dnsErr) && dnsErr.Err == errServerMisbehaving.Error()) { ++ t.Fatalf("r.tryOneName(): unexpected error: %v", err) ++ } ++} diff --git a/backport-0008-Backport-net-dns-client-avoid-potential-endless-loop.patch b/backport-0008-Backport-net-dns-client-avoid-potential-endless-loop.patch new file mode 100644 index 0000000..558be02 --- /dev/null +++ b/backport-0008-Backport-net-dns-client-avoid-potential-endless-loop.patch @@ -0,0 +1,35 @@ +From ddfab21e464b9b4c15fe3dc97eb5d93a4932f434 Mon Sep 17 00:00:00 2001 +From: Ian Lance Taylor +Date: Thu, 11 Apr 2024 14:36:25 -0700 +Subject: [PATCH] net: check SkipAdditional error result + +This will avoid a potential endless loop for a corrupt DNS packet. + +For #66754 + +Change-Id: I46591b3f7695bcc88d2312833e45955f8c129d2b +Reviewed-on: https://go-review.googlesource.com/c/go/+/578375 +Reviewed-by: Damien Neil +LUCI-TryBot-Result: Go LUCI +Commit-Queue: Ian Lance Taylor +Auto-Submit: Ian Lance Taylor +Reviewed-by: Ian Lance Taylor +--- + src/net/dnsclient_unix.go | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go +index e9e7e4df151f9..ad5c245dbf74b 100644 +--- a/src/net/dnsclient_unix.go ++++ b/src/net/dnsclient_unix.go +@@ -277,7 +277,9 @@ func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) (dnsmessag + if ahdr.Type == dnsmessage.TypeOPT { + return ahdr.ExtendedRCode(hdr.RCode), hasAdd + } +- p.SkipAdditional() ++ if err := p.SkipAdditional(); err != nil { ++ return hdr.RCode, hasAdd ++ } + } + } + diff --git a/golang.spec b/golang.spec index d214f53..f2fcebb 100644 --- a/golang.spec +++ b/golang.spec @@ -66,7 +66,7 @@ Name: golang Version: 1.21.4 -Release: 8 +Release: 9 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -126,6 +126,8 @@ Patch6003: backport-0003-release-branch.go1.21-net-textproto-mime-multipart-a.pa Patch6004: backport-0004-release-branch.go1.21-net-http-net-http-cookiejar-av.patch Patch6005: backport-0005-release-branch.go1.21-net-mail-properly-handle-speci.patch Patch6006: backport-0006-Backport-net-http-update-bundled-golang.org-x-net-ht.patch +Patch6007: backport-0007-Backport-net-dns-client-check-skip-additional-error.patch +Patch6008: backport-0008-Backport-net-dns-client-avoid-potential-endless-loop.patch ExclusiveArch: %{golang_arches} @@ -364,6 +366,9 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Sat May 11 2024 zhaosai - 1.21.4-9 +- fix CVE-2024-24788 + * Thu Apr 18 2024 Huang Yang - 1.21.4-8 - enable external_linker and cgo on loongarch64 -- Gitee