[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1033976: marked as done ([pre-approve] unblock: golang-1.19/1.19.8-2)



Your message dated Sat, 08 Apr 2023 09:16:21 +0000
with message-id <E1pl4gH-0099G0-TU@respighi.debian.org>
and subject line unblock golang-1.19
has caused the Debian Bug report #1033976,
regarding [pre-approve] unblock: golang-1.19/1.19.8-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1033976: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1033976
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: golang-1.19@packages.debian.org, zhsj@debian.org
Control: affects -1 + src:golang-1.19

Please unblock package golang-1.19

[ Reason ]
Two upstream minor versions, fixing 5 CVEs

+ CVE-2023-24532: crypto/elliptic: incorrect P-256 ScalarMult and
  ScalarBaseMult results
+ CVE-2023-24537: go/parser: infinite loop in parsing
+ CVE-2023-24538: html/template: backticks not treated as string delimiters
+ CVE-2023-24534: net/http, net/textproto: denial of service from excessive
  memory allocation
+ CVE-2023-24536: net/http, net/textproto, mime/multipart: denial of
  service from excessive resource consumption

[ Impact ]

Several security issues in the Go standard libraries.

[ Tests ]
Besise the unittests upstream added in the new release, I have use the new
version to build some Go packages. And the result is good.

[ Risks ]
Toolchain package and no autopkgtest.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

      I attached the debdiff with
      filterdiff --exclude '*_test.go' --exclude '*_windows*' --exclude '*/testdata/*' \
        --exclude '*/go.mod' --exclude '*/go.sum' --exclude '*/modules.txt'

[ Other info ]
It may be the last golang-1.19 version to be uploaded during freeze.
The next release is expected (if no urgent CVE happens) to be May, which
is probably hard-freeze time.

unblock golang-1.19/1.19.8-2
diff -Nru golang-1.19-1.19.6/debian/changelog golang-1.19-1.19.8/debian/changelog
--- golang-1.19-1.19.6/debian/changelog	2023-02-17 17:56:44.000000000 +0800
+++ golang-1.19-1.19.8/debian/changelog	2023-04-05 02:15:56.000000000 +0800
@@ -1,3 +1,25 @@
+golang-1.19 (1.19.8-1) experimental; urgency=medium
+
+  * Team upload
+  * New upstream version 1.19.8
+    + CVE-2023-24537: go/parser: infinite loop in parsing
+    + CVE-2023-24538: html/template: backticks not treated as string delimiters
+    + CVE-2023-24534: net/http, net/textproto: denial of service from excessive
+      memory allocation
+    + CVE-2023-24536: net/http, net/textproto, mime/multipart: denial of
+      service from excessive resource consumption
+
+ -- Shengjing Zhu <zhsj@debian.org>  Wed, 05 Apr 2023 02:15:56 +0800
+
+golang-1.19 (1.19.7-1) experimental; urgency=medium
+
+  * Team upload
+  * New upstream version 1.19.7
+    + CVE-2023-24532: crypto/elliptic: incorrect P-256 ScalarMult and
+      ScalarBaseMult results
+
+ -- Shengjing Zhu <zhsj@debian.org>  Wed, 08 Mar 2023 13:54:08 +0800
+
 golang-1.19 (1.19.6-2) unstable; urgency=medium
 
   * Team upload
diff -Nru golang-1.19-1.19.6/src/cmd/go/internal/work/exec.go golang-1.19-1.19.8/src/cmd/go/internal/work/exec.go
--- golang-1.19-1.19.6/src/cmd/go/internal/work/exec.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/go/internal/work/exec.go	2023-03-30 05:15:17.000000000 +0800
@@ -2764,6 +2764,36 @@
 		}
 	}
 
+	// Scrutinize CFLAGS and related for flags that might cause
+	// problems if we are using internal linking (for example, use of
+	// plugins, LTO, etc) by calling a helper routine that builds on
+	// the existing CGO flags allow-lists. If we see anything
+	// suspicious, emit a special token file "preferlinkext" (known to
+	// the linker) in the object file to signal the that it should not
+	// try to link internally and should revert to external linking.
+	// The token we pass is a suggestion, not a mandate; if a user is
+	// explicitly asking for a specific linkmode via the "-linkmode"
+	// flag, the token will be ignored. NB: in theory we could ditch
+	// the token approach and just pass a flag to the linker when we
+	// eventually invoke it, and the linker flag could then be
+	// documented (although coming up with a simple explanation of the
+	// flag might be challenging). For more context see issues #58619,
+	// #58620, and #58848.
+	flagSources := []string{"CGO_CFLAGS", "CGO_CXXFLAGS", "CGO_FFLAGS"}
+	flagLists := [][]string{cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS}
+	if flagsNotCompatibleWithInternalLinking(flagSources, flagLists) {
+		tokenFile := objdir + "preferlinkext"
+		if cfg.BuildN || cfg.BuildX {
+			b.Showcmd("", "echo > %s", tokenFile)
+		}
+		if !cfg.BuildN {
+			if err := os.WriteFile(tokenFile, nil, 0666); err != nil {
+				return nil, nil, err
+			}
+		}
+		outObj = append(outObj, tokenFile)
+	}
+
 	if cfg.BuildMSan {
 		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
 		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
@@ -3012,6 +3042,24 @@
 	return outGo, outObj, nil
 }
 
+// flagsNotCompatibleWithInternalLinking scans the list of cgo
+// compiler flags (C/C++/Fortran) looking for flags that might cause
+// problems if the build in question uses internal linking. The
+// primary culprits are use of plugins or use of LTO, but we err on
+// the side of caution, supporting only those flags that are on the
+// allow-list for safe flags from security perspective. Return is TRUE
+// if a sensitive flag is found, FALSE otherwise.
+func flagsNotCompatibleWithInternalLinking(sourceList []string, flagListList [][]string) bool {
+	for i := range sourceList {
+		sn := sourceList[i]
+		fll := flagListList[i]
+		if err := checkCompilerFlagsForInternalLink(sn, sn, fll); err != nil {
+			return true
+		}
+	}
+	return false
+}
+
 // dynimport creates a Go source file named importGo containing
 // //go:cgo_import_dynamic directives for each symbol or library
 // dynamically imported by the object files outObj.
diff -Nru golang-1.19-1.19.6/src/cmd/go/internal/work/security.go golang-1.19-1.19.8/src/cmd/go/internal/work/security.go
--- golang-1.19-1.19.6/src/cmd/go/internal/work/security.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/go/internal/work/security.go	2023-03-30 05:15:17.000000000 +0800
@@ -230,32 +230,55 @@
 }
 
 func checkCompilerFlags(name, source string, list []string) error {
-	return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg)
+	checkOverrides := true
+	return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
 }
 
 func checkLinkerFlags(name, source string, list []string) error {
-	return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg)
+	checkOverrides := true
+	return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
 }
 
-func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string) error {
+// checkCompilerFlagsForInternalLink returns an error if 'list'
+// contains a flag or flags that may not be fully supported by
+// internal linking (meaning that we should punt the link to the
+// external linker).
+func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
+	checkOverrides := false
+	if err := checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
+		return err
+	}
+	// Currently the only flag on the allow list that causes problems
+	// for the linker is "-flto"; check for it manually here.
+	for _, fl := range list {
+		if strings.HasPrefix(fl, "-flto") {
+			return fmt.Errorf("flag %q triggers external linking", fl)
+		}
+	}
+	return nil
+}
+
+func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
 	// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
 	var (
 		allow    *regexp.Regexp
 		disallow *regexp.Regexp
 	)
-	if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
-		r, err := regexp.Compile(env)
-		if err != nil {
-			return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
+	if checkOverrides {
+		if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
+			r, err := regexp.Compile(env)
+			if err != nil {
+				return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
+			}
+			allow = r
 		}
-		allow = r
-	}
-	if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
-		r, err := regexp.Compile(env)
-		if err != nil {
-			return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
+		if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
+			r, err := regexp.Compile(env)
+			if err != nil {
+				return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
+			}
+			disallow = r
 		}
-		disallow = r
 	}
 
 Args:
diff -Nru golang-1.19-1.19.6/src/cmd/internal/obj/ppc64/asm9.go golang-1.19-1.19.8/src/cmd/internal/obj/ppc64/asm9.go
--- golang-1.19-1.19.6/src/cmd/internal/obj/ppc64/asm9.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/internal/obj/ppc64/asm9.go	2023-03-30 05:15:17.000000000 +0800
@@ -3136,8 +3136,13 @@
 		if r == 0 {
 			r = c.getimpliedreg(&p.From, p)
 		}
-		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v)))
-		o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
+		if o.a6 == C_REG {
+			o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v)))
+			o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
+		} else {
+			o1 = AOP_IRR(OP_ADDIS, uint32(REGTMP), uint32(r), uint32(high16adjusted(v)))
+			o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(REGTMP), uint32(v))
+		}
 
 		// Sign extend MOVB if needed
 		o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
@@ -3516,8 +3521,8 @@
 				rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
 			}
 		default:
-			reuseBaseReg := p.As != AFMOVD && p.As != AFMOVS
-			// Reuse To.Reg as base register if not FP move.
+			reuseBaseReg := o.a6 == C_REG
+			// Reuse To.Reg as base register if it is a GPR.
 			o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst, reuseBaseReg)
 		}
 
diff -Nru golang-1.19-1.19.6/src/cmd/link/internal/arm/asm.go golang-1.19-1.19.8/src/cmd/link/internal/arm/asm.go
--- golang-1.19-1.19.6/src/cmd/link/internal/arm/asm.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/link/internal/arm/asm.go	2023-03-30 05:15:17.000000000 +0800
@@ -396,11 +396,28 @@
 		// laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
 		// in dependency order.
 		if ldr.SymValue(rs) != 0 {
-			// r.Add is the instruction
-			// low 24-bit encodes the target address
-			t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			// Workaround for issue #58425: it appears that the
+			// external linker doesn't always take into account the
+			// relocation addend when doing reachability checks. This
+			// means that if you have a call from function XYZ at
+			// offset 8 to runtime.duffzero with addend 800 (for
+			// example), where the distance between the start of XYZ
+			// and the start of runtime.duffzero is just over the
+			// limit (by 100 bytes, say), you can get "relocation
+			// doesn't fit" errors from the external linker. To deal
+			// with this, ignore the addend when performing the
+			// distance calculation (this assumes that we're only
+			// handling backward jumps; ideally we might want to check
+			// both with and without the addend).
+			if ctxt.IsExternal() {
+				t = (ldr.SymValue(rs) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			} else {
+				// r.Add is the instruction
+				// low 24-bit encodes the target address
+				t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			}
 		}
-		if t > 0x7fffff || t < -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
+		if t > 0x7fffff || t <= -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
 			// direct call too far, need to insert trampoline.
 			// look up existing trampolines first. if we found one within the range
 			// of direct call, we can reuse it. otherwise create a new one.
diff -Nru golang-1.19-1.19.6/src/cmd/link/internal/ld/config.go golang-1.19-1.19.8/src/cmd/link/internal/ld/config.go
--- golang-1.19-1.19.6/src/cmd/link/internal/ld/config.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/link/internal/ld/config.go	2023-03-30 05:15:17.000000000 +0800
@@ -280,7 +280,11 @@
 			ctxt.LinkMode = LinkExternal
 			via = "via GO_EXTLINK_ENABLED "
 		default:
-			if extNeeded || (iscgo && externalobj) {
+			preferExternal := len(preferlinkext) != 0
+			if preferExternal && ctxt.Debugvlog > 0 {
+				ctxt.Logf("external linking prefer list is %v\n", preferlinkext)
+			}
+			if extNeeded || (iscgo && (externalobj || preferExternal)) {
 				ctxt.LinkMode = LinkExternal
 			} else {
 				ctxt.LinkMode = LinkInternal
diff -Nru golang-1.19-1.19.6/src/cmd/link/internal/ld/lib.go golang-1.19-1.19.8/src/cmd/link/internal/ld/lib.go
--- golang-1.19-1.19.6/src/cmd/link/internal/ld/lib.go	2023-02-14 01:38:43.000000000 +0800
+++ golang-1.19-1.19.8/src/cmd/link/internal/ld/lib.go	2023-03-30 05:15:17.000000000 +0800
@@ -349,6 +349,12 @@
 	// any of these objects, we must link externally. Issue 52863.
 	dynimportfail []string
 
+	// preferlinkext is a list of packages for which the Go command
+	// noticed use of peculiar C flags. If we see any of these,
+	// default to linking externally unless overridden by the
+	// user. See issues #58619, #58620, and #58848.
+	preferlinkext []string
+
 	// unknownObjFormat is set to true if we see an object whose
 	// format we don't recognize.
 	unknownObjFormat = false
@@ -1043,6 +1049,13 @@
 		if arhdr.name == "dynimportfail" {
 			dynimportfail = append(dynimportfail, lib.Pkg)
 		}
+		if arhdr.name == "preferlinkext" {
+			// Ignore this directive if -linkmode has been
+			// set explicitly.
+			if ctxt.LinkMode == LinkAuto {
+				preferlinkext = append(preferlinkext, lib.Pkg)
+			}
+		}
 
 		// Skip other special (non-object-file) sections that
 		// build tools may have added. Such sections must have
diff -Nru golang-1.19-1.19.6/src/crypto/internal/nistec/p256_asm.go golang-1.19-1.19.8/src/crypto/internal/nistec/p256_asm.go
--- golang-1.19-1.19.6/src/crypto/internal/nistec/p256_asm.go	2023-02-14 01:38:45.000000000 +0800
+++ golang-1.19-1.19.8/src/crypto/internal/nistec/p256_asm.go	2023-03-30 05:15:20.000000000 +0800
@@ -365,6 +365,21 @@
 // Montgomery domain (with R 2²⁵⁶) as four uint64 limbs in little-endian order.
 type p256OrdElement [4]uint64
 
+// p256OrdReduce ensures s is in the range [0, ord(G)-1].
+func p256OrdReduce(s *p256OrdElement) {
+	// Since 2 * ord(G) > 2²⁵⁶, we can just conditionally subtract ord(G),
+	// keeping the result if it doesn't underflow.
+	t0, b := bits.Sub64(s[0], 0xf3b9cac2fc632551, 0)
+	t1, b := bits.Sub64(s[1], 0xbce6faada7179e84, b)
+	t2, b := bits.Sub64(s[2], 0xffffffffffffffff, b)
+	t3, b := bits.Sub64(s[3], 0xffffffff00000000, b)
+	tMask := b - 1 // zero if subtraction underflowed
+	s[0] ^= (t0 ^ s[0]) & tMask
+	s[1] ^= (t1 ^ s[1]) & tMask
+	s[2] ^= (t2 ^ s[2]) & tMask
+	s[3] ^= (t3 ^ s[3]) & tMask
+}
+
 // Add sets q = p1 + p2, and returns q. The points may overlap.
 func (q *P256Point) Add(r1, r2 *P256Point) *P256Point {
 	var sum, double P256Point
@@ -394,6 +409,7 @@
 	}
 	scalarReversed := new(p256OrdElement)
 	p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
+	p256OrdReduce(scalarReversed)
 
 	r.p256BaseMult(scalarReversed)
 	return r, nil
@@ -408,6 +424,7 @@
 	}
 	scalarReversed := new(p256OrdElement)
 	p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
+	p256OrdReduce(scalarReversed)
 
 	r.Set(q).p256ScalarMult(scalarReversed)
 	return r, nil
diff -Nru golang-1.19-1.19.6/src/crypto/internal/nistec/p256_asm_ordinv.go golang-1.19-1.19.8/src/crypto/internal/nistec/p256_asm_ordinv.go
--- golang-1.19-1.19.6/src/crypto/internal/nistec/p256_asm_ordinv.go	2023-02-14 01:38:45.000000000 +0800
+++ golang-1.19-1.19.8/src/crypto/internal/nistec/p256_asm_ordinv.go	2023-03-30 05:15:20.000000000 +0800
@@ -25,6 +25,7 @@
 
 	x := new(p256OrdElement)
 	p256OrdBigToLittle(x, (*[32]byte)(k))
+	p256OrdReduce(x)
 
 	// Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem.
 	//
diff -Nru golang-1.19-1.19.6/src/crypto/x509/root_darwin.go golang-1.19-1.19.8/src/crypto/x509/root_darwin.go
--- golang-1.19-1.19.6/src/crypto/x509/root_darwin.go	2023-02-14 01:38:45.000000000 +0800
+++ golang-1.19-1.19.8/src/crypto/x509/root_darwin.go	2023-03-30 05:15:20.000000000 +0800
@@ -25,9 +25,10 @@
 				return nil, err
 			}
 			sc, err := macOS.SecCertificateCreateWithData(c.Raw)
-			if err == nil {
-				macOS.CFArrayAppendValue(certs, sc)
+			if err != nil {
+				return nil, err
 			}
+			macOS.CFArrayAppendValue(certs, sc)
 		}
 	}
 
diff -Nru golang-1.19-1.19.6/src/go/scanner/scanner.go golang-1.19-1.19.8/src/go/scanner/scanner.go
--- golang-1.19-1.19.6/src/go/scanner/scanner.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/go/scanner/scanner.go	2023-03-30 05:15:20.000000000 +0800
@@ -246,13 +246,16 @@
 		return
 	}
 
+	// Put a cap on the maximum size of line and column numbers.
+	// 30 bits allows for some additional space before wrapping an int32.
+	const maxLineCol = 1<<30 - 1
 	var line, col int
 	i2, n2, ok2 := trailingDigits(text[:i-1])
 	if ok2 {
 		//line filename:line:col
 		i, i2 = i2, i
 		line, col = n2, n
-		if col == 0 {
+		if col == 0 || col > maxLineCol {
 			s.error(offs+i2, "invalid column number: "+string(text[i2:]))
 			return
 		}
@@ -262,7 +265,7 @@
 		line = n
 	}
 
-	if line == 0 {
+	if line == 0 || line > maxLineCol {
 		s.error(offs+i, "invalid line number: "+string(text[i:]))
 		return
 	}
diff -Nru golang-1.19-1.19.6/src/html/template/context.go golang-1.19-1.19.8/src/html/template/context.go
--- golang-1.19-1.19.6/src/html/template/context.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/context.go	2023-03-30 05:15:20.000000000 +0800
@@ -120,6 +120,8 @@
 	stateJSDqStr
 	// stateJSSqStr occurs inside a JavaScript single quoted string.
 	stateJSSqStr
+	// stateJSBqStr occurs inside a JavaScript back quoted string.
+	stateJSBqStr
 	// stateJSRegexp occurs inside a JavaScript regexp literal.
 	stateJSRegexp
 	// stateJSBlockCmt occurs inside a JavaScript /* block comment */.
diff -Nru golang-1.19-1.19.6/src/html/template/error.go golang-1.19-1.19.8/src/html/template/error.go
--- golang-1.19-1.19.6/src/html/template/error.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/error.go	2023-03-30 05:15:20.000000000 +0800
@@ -214,6 +214,19 @@
 	//   pipeline occurs in an unquoted attribute value context, "html" is
 	//   disallowed. Avoid using "html" and "urlquery" entirely in new templates.
 	ErrPredefinedEscaper
+
+	// errJSTmplLit: "... appears in a JS template literal"
+	// Example:
+	//     <script>var tmpl = `{{.Interp}`</script>
+	// Discussion:
+	//   Package html/template does not support actions inside of JS template
+	//   literals.
+	//
+	// TODO(rolandshoemaker): we cannot add this as an exported error in a minor
+	// release, since it is backwards incompatible with the other minor
+	// releases. As such we need to leave it unexported, and then we'll add it
+	// in the next major release.
+	errJSTmplLit
 )
 
 func (e *Error) Error() string {
diff -Nru golang-1.19-1.19.6/src/html/template/escape.go golang-1.19-1.19.8/src/html/template/escape.go
--- golang-1.19-1.19.6/src/html/template/escape.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/escape.go	2023-03-30 05:15:20.000000000 +0800
@@ -8,6 +8,7 @@
 	"bytes"
 	"fmt"
 	"html"
+	"internal/godebug"
 	"io"
 	"text/template"
 	"text/template/parse"
@@ -223,6 +224,16 @@
 		c.jsCtx = jsCtxDivOp
 	case stateJSDqStr, stateJSSqStr:
 		s = append(s, "_html_template_jsstrescaper")
+	case stateJSBqStr:
+		debugAllowActionJSTmpl := godebug.Get("jstmpllitinterp")
+		if debugAllowActionJSTmpl == "1" {
+			s = append(s, "_html_template_jsstrescaper")
+		} else {
+			return context{
+				state: stateError,
+				err:   errorf(errJSTmplLit, n, n.Line, "%s appears in a JS template literal", n),
+			}
+		}
 	case stateJSRegexp:
 		s = append(s, "_html_template_jsregexpescaper")
 	case stateCSS:
diff -Nru golang-1.19-1.19.6/src/html/template/jsctx_string.go golang-1.19-1.19.8/src/html/template/jsctx_string.go
--- golang-1.19-1.19.6/src/html/template/jsctx_string.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/jsctx_string.go	2023-03-30 05:15:21.000000000 +0800
@@ -4,6 +4,15 @@
 
 import "strconv"
 
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[jsCtxRegexp-0]
+	_ = x[jsCtxDivOp-1]
+	_ = x[jsCtxUnknown-2]
+}
+
 const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown"
 
 var _jsCtx_index = [...]uint8{0, 11, 21, 33}
diff -Nru golang-1.19-1.19.6/src/html/template/js.go golang-1.19-1.19.8/src/html/template/js.go
--- golang-1.19-1.19.6/src/html/template/js.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/js.go	2023-03-30 05:15:21.000000000 +0800
@@ -308,6 +308,7 @@
 	// Encode HTML specials as hex so the output can be embedded
 	// in HTML attributes without further encoding.
 	'"':  `\u0022`,
+	'`':  `\u0060`,
 	'&':  `\u0026`,
 	'\'': `\u0027`,
 	'+':  `\u002b`,
@@ -331,6 +332,7 @@
 	'"':  `\u0022`,
 	'&':  `\u0026`,
 	'\'': `\u0027`,
+	'`':  `\u0060`,
 	'+':  `\u002b`,
 	'/':  `\/`,
 	'<':  `\u003c`,
diff -Nru golang-1.19-1.19.6/src/html/template/state_string.go golang-1.19-1.19.8/src/html/template/state_string.go
--- golang-1.19-1.19.6/src/html/template/state_string.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/state_string.go	2023-03-30 05:15:21.000000000 +0800
@@ -4,9 +4,42 @@
 
 import "strconv"
 
-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError"
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[stateText-0]
+	_ = x[stateTag-1]
+	_ = x[stateAttrName-2]
+	_ = x[stateAfterName-3]
+	_ = x[stateBeforeValue-4]
+	_ = x[stateHTMLCmt-5]
+	_ = x[stateRCDATA-6]
+	_ = x[stateAttr-7]
+	_ = x[stateURL-8]
+	_ = x[stateSrcset-9]
+	_ = x[stateJS-10]
+	_ = x[stateJSDqStr-11]
+	_ = x[stateJSSqStr-12]
+	_ = x[stateJSBqStr-13]
+	_ = x[stateJSRegexp-14]
+	_ = x[stateJSBlockCmt-15]
+	_ = x[stateJSLineCmt-16]
+	_ = x[stateCSS-17]
+	_ = x[stateCSSDqStr-18]
+	_ = x[stateCSSSqStr-19]
+	_ = x[stateCSSDqURL-20]
+	_ = x[stateCSSSqURL-21]
+	_ = x[stateCSSURL-22]
+	_ = x[stateCSSBlockCmt-23]
+	_ = x[stateCSSLineCmt-24]
+	_ = x[stateError-25]
+	_ = x[stateDead-26]
+}
 
-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 155, 170, 184, 192, 205, 218, 231, 244, 255, 271, 286, 296}
+const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
+
+var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317}
 
 func (i state) String() string {
 	if i >= state(len(_state_index)-1) {
diff -Nru golang-1.19-1.19.6/src/html/template/transition.go golang-1.19-1.19.8/src/html/template/transition.go
--- golang-1.19-1.19.6/src/html/template/transition.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/html/template/transition.go	2023-03-30 05:15:21.000000000 +0800
@@ -27,6 +27,7 @@
 	stateJS:          tJS,
 	stateJSDqStr:     tJSDelimited,
 	stateJSSqStr:     tJSDelimited,
+	stateJSBqStr:     tJSDelimited,
 	stateJSRegexp:    tJSDelimited,
 	stateJSBlockCmt:  tBlockCmt,
 	stateJSLineCmt:   tLineCmt,
@@ -262,7 +263,7 @@
 
 // tJS is the context transition function for the JS state.
 func tJS(c context, s []byte) (context, int) {
-	i := bytes.IndexAny(s, `"'/`)
+	i := bytes.IndexAny(s, "\"`'/")
 	if i == -1 {
 		// Entire input is non string, comment, regexp tokens.
 		c.jsCtx = nextJSCtx(s, c.jsCtx)
@@ -274,6 +275,8 @@
 		c.state, c.jsCtx = stateJSDqStr, jsCtxRegexp
 	case '\'':
 		c.state, c.jsCtx = stateJSSqStr, jsCtxRegexp
+	case '`':
+		c.state, c.jsCtx = stateJSBqStr, jsCtxRegexp
 	case '/':
 		switch {
 		case i+1 < len(s) && s[i+1] == '/':
@@ -303,6 +306,8 @@
 	switch c.state {
 	case stateJSSqStr:
 		specials = `\'`
+	case stateJSBqStr:
+		specials = "`\\"
 	case stateJSRegexp:
 		specials = `\/[]`
 	}
diff -Nru golang-1.19-1.19.6/src/internal/poll/fd_poll_runtime.go golang-1.19-1.19.8/src/internal/poll/fd_poll_runtime.go
--- golang-1.19-1.19.6/src/internal/poll/fd_poll_runtime.go	2023-02-14 01:38:46.000000000 +0800
+++ golang-1.19-1.19.8/src/internal/poll/fd_poll_runtime.go	2023-03-30 05:15:21.000000000 +0800
@@ -23,7 +23,7 @@
 func runtime_pollOpen(fd uintptr) (uintptr, int)
 func runtime_pollClose(ctx uintptr)
 func runtime_pollWait(ctx uintptr, mode int) int
-func runtime_pollWaitCanceled(ctx uintptr, mode int) int
+func runtime_pollWaitCanceled(ctx uintptr, mode int)
 func runtime_pollReset(ctx uintptr, mode int) int
 func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
 func runtime_pollUnblock(ctx uintptr)
diff -Nru golang-1.19-1.19.6/src/mime/multipart/formdata.go golang-1.19-1.19.8/src/mime/multipart/formdata.go
--- golang-1.19-1.19.6/src/mime/multipart/formdata.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/mime/multipart/formdata.go	2023-03-30 05:15:21.000000000 +0800
@@ -12,6 +12,7 @@
 	"math"
 	"net/textproto"
 	"os"
+	"strconv"
 )
 
 // ErrMessageTooLarge is returned by ReadForm if the message form
@@ -41,6 +42,15 @@
 	numDiskFiles := 0
 	multipartFiles := godebug.Get("multipartfiles")
 	combineFiles := multipartFiles != "distinct"
+	maxParts := 1000
+	multipartMaxParts := godebug.Get("multipartmaxparts")
+	if multipartMaxParts != "" {
+		if v, err := strconv.Atoi(multipartMaxParts); err == nil && v >= 0 {
+			maxParts = v
+		}
+	}
+	maxHeaders := maxMIMEHeaders()
+
 	defer func() {
 		if file != nil {
 			if cerr := file.Close(); err == nil {
@@ -84,14 +94,19 @@
 			maxMemoryBytes = math.MaxInt64
 		}
 	}
+	var copyBuf []byte
 	for {
-		p, err := r.nextPart(false, maxMemoryBytes)
+		p, err := r.nextPart(false, maxMemoryBytes, maxHeaders)
 		if err == io.EOF {
 			break
 		}
 		if err != nil {
 			return nil, err
 		}
+		if maxParts <= 0 {
+			return nil, ErrMessageTooLarge
+		}
+		maxParts--
 
 		name := p.FormName()
 		if name == "" {
@@ -102,8 +117,9 @@
 		// Multiple values for the same key (one map entry, longer slice) are cheaper
 		// than the same number of values for different keys (many map entries), but
 		// using a consistent per-value cost for overhead is simpler.
+		const mapEntryOverhead = 200
 		maxMemoryBytes -= int64(len(name))
-		maxMemoryBytes -= 100 // map overhead
+		maxMemoryBytes -= mapEntryOverhead
 		if maxMemoryBytes < 0 {
 			// We can't actually take this path, since nextPart would already have
 			// rejected the MIME headers for being too large. Check anyway.
@@ -127,10 +143,16 @@
 		}
 
 		// file, store in memory or on disk
+		const fileHeaderSize = 100
 		maxMemoryBytes -= mimeHeaderSize(p.Header)
+		maxMemoryBytes -= mapEntryOverhead
+		maxMemoryBytes -= fileHeaderSize
 		if maxMemoryBytes < 0 {
 			return nil, ErrMessageTooLarge
 		}
+		for _, v := range p.Header {
+			maxHeaders -= int64(len(v))
+		}
 		fh := &FileHeader{
 			Filename: filename,
 			Header:   p.Header,
@@ -147,14 +169,22 @@
 				}
 			}
 			numDiskFiles++
-			size, err := io.Copy(file, io.MultiReader(&b, p))
+			if _, err := file.Write(b.Bytes()); err != nil {
+				return nil, err
+			}
+			if copyBuf == nil {
+				copyBuf = make([]byte, 32*1024) // same buffer size as io.Copy uses
+			}
+			// os.File.ReadFrom will allocate its own copy buffer if we let io.Copy use it.
+			type writerOnly struct{ io.Writer }
+			remainingSize, err := io.CopyBuffer(writerOnly{file}, p, copyBuf)
 			if err != nil {
 				return nil, err
 			}
 			fh.tmpfile = file.Name()
-			fh.Size = size
+			fh.Size = int64(b.Len()) + remainingSize
 			fh.tmpoff = fileOff
-			fileOff += size
+			fileOff += fh.Size
 			if !combineFiles {
 				if err := file.Close(); err != nil {
 					return nil, err
@@ -174,9 +204,10 @@
 }
 
 func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
+	size = 400
 	for k, vs := range h {
 		size += int64(len(k))
-		size += 100 // map entry overhead
+		size += 200 // map entry overhead
 		for _, v := range vs {
 			size += int64(len(v))
 		}
diff -Nru golang-1.19-1.19.6/src/mime/multipart/multipart.go golang-1.19-1.19.8/src/mime/multipart/multipart.go
--- golang-1.19-1.19.6/src/mime/multipart/multipart.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/mime/multipart/multipart.go	2023-03-30 05:15:21.000000000 +0800
@@ -16,11 +16,13 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"internal/godebug"
 	"io"
 	"mime"
 	"mime/quotedprintable"
 	"net/textproto"
 	"path/filepath"
+	"strconv"
 	"strings"
 )
 
@@ -128,12 +130,12 @@
 	return n, r.err
 }
 
-func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize int64) (*Part, error) {
+func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
 	bp := &Part{
 		Header: make(map[string][]string),
 		mr:     mr,
 	}
-	if err := bp.populateHeaders(maxMIMEHeaderSize); err != nil {
+	if err := bp.populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders); err != nil {
 		return nil, err
 	}
 	bp.r = partReader{bp}
@@ -149,9 +151,9 @@
 	return bp, nil
 }
 
-func (p *Part) populateHeaders(maxMIMEHeaderSize int64) error {
+func (p *Part) populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders int64) error {
 	r := textproto.NewReader(p.mr.bufReader)
-	header, err := readMIMEHeader(r, maxMIMEHeaderSize)
+	header, err := readMIMEHeader(r, maxMIMEHeaderSize, maxMIMEHeaders)
 	if err == nil {
 		p.Header = header
 	}
@@ -330,6 +332,19 @@
 // including header keys, values, and map overhead.
 const maxMIMEHeaderSize = 10 << 20
 
+func maxMIMEHeaders() int64 {
+	// multipartMaxHeaders is the maximum number of header entries NextPart will return,
+	// as well as the maximum combined total of header entries Reader.ReadForm will return
+	// in FileHeaders.
+	multipartMaxHeaders := godebug.Get("multipartmaxheaders")
+	if multipartMaxHeaders != "" {
+		if v, err := strconv.ParseInt(multipartMaxHeaders, 10, 64); err == nil && v >= 0 {
+			return v
+		}
+	}
+	return 10000
+}
+
 // NextPart returns the next part in the multipart or an error.
 // When there are no more parts, the error io.EOF is returned.
 //
@@ -337,7 +352,7 @@
 // has a value of "quoted-printable", that header is instead
 // hidden and the body is transparently decoded during Read calls.
 func (r *Reader) NextPart() (*Part, error) {
-	return r.nextPart(false, maxMIMEHeaderSize)
+	return r.nextPart(false, maxMIMEHeaderSize, maxMIMEHeaders())
 }
 
 // NextRawPart returns the next part in the multipart or an error.
@@ -346,10 +361,10 @@
 // Unlike NextPart, it does not have special handling for
 // "Content-Transfer-Encoding: quoted-printable".
 func (r *Reader) NextRawPart() (*Part, error) {
-	return r.nextPart(true, maxMIMEHeaderSize)
+	return r.nextPart(true, maxMIMEHeaderSize, maxMIMEHeaders())
 }
 
-func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize int64) (*Part, error) {
+func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
 	if r.currentPart != nil {
 		r.currentPart.Close()
 	}
@@ -374,7 +389,7 @@
 
 		if r.isBoundaryDelimiterLine(line) {
 			r.partsRead++
-			bp, err := newPart(r, rawPart, maxMIMEHeaderSize)
+			bp, err := newPart(r, rawPart, maxMIMEHeaderSize, maxMIMEHeaders)
 			if err != nil {
 				return nil, err
 			}
diff -Nru golang-1.19-1.19.6/src/mime/multipart/readmimeheader.go golang-1.19-1.19.8/src/mime/multipart/readmimeheader.go
--- golang-1.19-1.19.6/src/mime/multipart/readmimeheader.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/mime/multipart/readmimeheader.go	2023-03-30 05:15:21.000000000 +0800
@@ -11,4 +11,4 @@
 // readMIMEHeader is defined in package net/textproto.
 //
 //go:linkname readMIMEHeader net/textproto.readMIMEHeader
-func readMIMEHeader(r *textproto.Reader, lim int64) (textproto.MIMEHeader, error)
+func readMIMEHeader(r *textproto.Reader, maxMemory, maxHeaders int64) (textproto.MIMEHeader, error)
diff -Nru golang-1.19-1.19.6/src/net/textproto/reader.go golang-1.19-1.19.8/src/net/textproto/reader.go
--- golang-1.19-1.19.6/src/net/textproto/reader.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/net/textproto/reader.go	2023-03-30 05:15:21.000000000 +0800
@@ -483,23 +483,32 @@
 //		"Long-Key": {"Even Longer Value"},
 //	}
 func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
-	return readMIMEHeader(r, math.MaxInt64)
+	return readMIMEHeader(r, math.MaxInt64, math.MaxInt64)
 }
 
 // readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the header size.
 // It is called by the mime/multipart package.
-func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) {
+func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error) {
 	// Avoid lots of small slice allocations later by allocating one
 	// large one ahead of time which we'll cut up into smaller
 	// slices. If this isn't big enough later, we allocate small ones.
 	var strs []string
-	hint := r.upcomingHeaderNewlines()
+	hint := r.upcomingHeaderKeys()
 	if hint > 0 {
+		if hint > 1000 {
+			hint = 1000 // set a cap to avoid overallocation
+		}
 		strs = make([]string, hint)
 	}
 
 	m := make(MIMEHeader, hint)
 
+	// Account for 400 bytes of overhead for the MIMEHeader, plus 200 bytes per entry.
+	// Benchmarking map creation as of go1.20, a one-entry MIMEHeader is 416 bytes and large
+	// MIMEHeaders average about 200 bytes per entry.
+	maxMemory -= 400
+	const mapEntryOverhead = 200
+
 	// The first line cannot start with a leading space.
 	if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
 		line, err := r.readLineSlice()
@@ -529,16 +538,21 @@
 			continue
 		}
 
+		maxHeaders--
+		if maxHeaders < 0 {
+			return nil, errors.New("message too large")
+		}
+
 		// Skip initial spaces in value.
 		value := string(bytes.TrimLeft(v, " \t"))
 
 		vv := m[key]
 		if vv == nil {
-			lim -= int64(len(key))
-			lim -= 100 // map entry overhead
+			maxMemory -= int64(len(key))
+			maxMemory -= mapEntryOverhead
 		}
-		lim -= int64(len(value))
-		if lim < 0 {
+		maxMemory -= int64(len(value))
+		if maxMemory < 0 {
 			// TODO: This should be a distinguishable error (ErrMessageTooLarge)
 			// to allow mime/multipart to detect it.
 			return m, errors.New("message too large")
@@ -577,9 +591,9 @@
 
 var nl = []byte("\n")
 
-// upcomingHeaderNewlines returns an approximation of the number of newlines
+// upcomingHeaderKeys returns an approximation of the number of keys
 // that will be in this header. If it gets confused, it returns 0.
-func (r *Reader) upcomingHeaderNewlines() (n int) {
+func (r *Reader) upcomingHeaderKeys() (n int) {
 	// Try to determine the 'hint' size.
 	r.R.Peek(1) // force a buffer load if empty
 	s := r.R.Buffered()
@@ -587,7 +601,20 @@
 		return
 	}
 	peek, _ := r.R.Peek(s)
-	return bytes.Count(peek, nl)
+	for len(peek) > 0 && n < 1000 {
+		var line []byte
+		line, peek, _ = bytes.Cut(peek, nl)
+		if len(line) == 0 || (len(line) == 1 && line[0] == '\r') {
+			// Blank line separating headers from the body.
+			break
+		}
+		if line[0] == ' ' || line[0] == '\t' {
+			// Folded continuation of the previous line.
+			continue
+		}
+		n++
+	}
+	return n
 }
 
 // CanonicalMIMEHeaderKey returns the canonical format of the
diff -Nru golang-1.19-1.19.6/src/os/signal/internal/pty/pty.go golang-1.19-1.19.8/src/os/signal/internal/pty/pty.go
--- golang-1.19-1.19.6/src/os/signal/internal/pty/pty.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/os/signal/internal/pty/pty.go	2023-03-30 05:15:22.000000000 +0800
@@ -42,14 +42,14 @@
 // Open returns a control pty and the name of the linked process tty.
 func Open() (pty *os.File, processTTY string, err error) {
 	m, err := C.posix_openpt(C.O_RDWR)
-	if err != nil {
+	if m < 0 {
 		return nil, "", ptyError("posix_openpt", err)
 	}
-	if _, err := C.grantpt(m); err != nil {
+	if res, err := C.grantpt(m); res < 0 {
 		C.close(m)
 		return nil, "", ptyError("grantpt", err)
 	}
-	if _, err := C.unlockpt(m); err != nil {
+	if res, err := C.unlockpt(m); res < 0 {
 		C.close(m)
 		return nil, "", ptyError("unlockpt", err)
 	}
diff -Nru golang-1.19-1.19.6/src/runtime/mgcsweep.go golang-1.19-1.19.8/src/runtime/mgcsweep.go
--- golang-1.19-1.19.6/src/runtime/mgcsweep.go	2023-02-14 01:38:47.000000000 +0800
+++ golang-1.19-1.19.8/src/runtime/mgcsweep.go	2023-03-30 05:15:22.000000000 +0800
@@ -815,11 +815,30 @@
 		traceGCSweepStart()
 	}
 
+	// Fix debt if necessary.
 retry:
 	sweptBasis := mheap_.pagesSweptBasis.Load()
-
-	// Fix debt if necessary.
-	newHeapLive := uintptr(atomic.Load64(&gcController.heapLive)-mheap_.sweepHeapLiveBasis) + spanBytes
+	live := atomic.Load64(&gcController.heapLive)
+	liveBasis := mheap_.sweepHeapLiveBasis
+	newHeapLive := spanBytes
+	if liveBasis < live {
+		// Only do this subtraction when we don't overflow. Otherwise, pagesTarget
+		// might be computed as something really huge, causing us to get stuck
+		// sweeping here until the next mark phase.
+		//
+		// Overflow can happen here if gcPaceSweeper is called concurrently with
+		// sweeping (i.e. not during a STW, like it usually is) because this code
+		// is intentionally racy. A concurrent call to gcPaceSweeper can happen
+		// if a GC tuning parameter is modified and we read an older value of
+		// heapLive than what was used to set the basis.
+		//
+		// This state should be transient, so it's fine to just let newHeapLive
+		// be a relatively small number. We'll probably just skip this attempt to
+		// sweep.
+		//
+		// See issue #57523.
+		newHeapLive += uintptr(live - liveBasis)
+	}
 	pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
 	for pagesTarget > int64(mheap_.pagesSwept.Load()-sweptBasis) {
 		if sweepone() == ^uintptr(0) {
diff -Nru golang-1.19-1.19.6/src/sync/atomic/value.go golang-1.19-1.19.8/src/sync/atomic/value.go
--- golang-1.19-1.19.6/src/sync/atomic/value.go	2023-02-14 01:38:48.000000000 +0800
+++ golang-1.19-1.19.8/src/sync/atomic/value.go	2023-03-30 05:15:23.000000000 +0800
@@ -190,5 +190,5 @@
 }
 
 // Disable/enable preemption, implemented in runtime.
-func runtime_procPin()
+func runtime_procPin() int
 func runtime_procUnpin()
diff -Nru golang-1.19-1.19.6/src/time/zoneinfo.go golang-1.19-1.19.8/src/time/zoneinfo.go
--- golang-1.19-1.19.6/src/time/zoneinfo.go	2023-02-14 01:38:48.000000000 +0800
+++ golang-1.19-1.19.8/src/time/zoneinfo.go	2023-03-30 05:15:24.000000000 +0800
@@ -182,7 +182,7 @@
 	// If we're at the end of the known zone transitions,
 	// try the extend string.
 	if lo == len(tx)-1 && l.extend != "" {
-		if ename, eoffset, estart, eend, eisDST, ok := tzset(l.extend, end, sec); ok {
+		if ename, eoffset, estart, eend, eisDST, ok := tzset(l.extend, start, sec); ok {
 			return ename, eoffset, estart, eend, eisDST
 		}
 	}
@@ -243,12 +243,12 @@
 }
 
 // tzset takes a timezone string like the one found in the TZ environment
-// variable, the end of the last time zone transition expressed as seconds
+// variable, the time of the last time zone transition expressed as seconds
 // since January 1, 1970 00:00:00 UTC, and a time expressed the same way.
 // We call this a tzset string since in C the function tzset reads TZ.
 // The return values are as for lookup, plus ok which reports whether the
 // parse succeeded.
-func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, isDST, ok bool) {
+func tzset(s string, lastTxSec, sec int64) (name string, offset int, start, end int64, isDST, ok bool) {
 	var (
 		stdName, dstName     string
 		stdOffset, dstOffset int
@@ -269,7 +269,7 @@
 
 	if len(s) == 0 || s[0] == ',' {
 		// No daylight savings time.
-		return stdName, stdOffset, initEnd, omega, false, true
+		return stdName, stdOffset, lastTxSec, omega, false, true
 	}
 
 	dstName, s, ok = tzsetName(s)
diff -Nru golang-1.19-1.19.6/src/time/zoneinfo_read.go golang-1.19-1.19.8/src/time/zoneinfo_read.go
--- golang-1.19-1.19.6/src/time/zoneinfo_read.go	2023-02-14 01:38:48.000000000 +0800
+++ golang-1.19-1.19.8/src/time/zoneinfo_read.go	2023-03-30 05:15:24.000000000 +0800
@@ -329,7 +329,7 @@
 			} else if l.extend != "" {
 				// If we're at the end of the known zone transitions,
 				// try the extend string.
-				if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+				if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheStart, sec); ok {
 					l.cacheStart = estart
 					l.cacheEnd = eend
 					// Find the zone that is returned by tzset to avoid allocation if possible.
diff -Nru golang-1.19-1.19.6/VERSION golang-1.19-1.19.8/VERSION
--- golang-1.19-1.19.6/VERSION	2023-02-14 01:38:41.000000000 +0800
+++ golang-1.19-1.19.8/VERSION	2023-03-30 05:15:14.000000000 +0800
@@ -1 +1 @@
-go1.19.6
\ No newline at end of file
+go1.19.8
\ No newline at end of file

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: