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

Bug#1005340: marked as done (bullseye-pu: package golang-1.15/1.15.15-1~deb11u3)



Your message dated Sat, 26 Mar 2022 11:59:13 +0000
with message-id <c4d20274f6d76a43fb574d2177f6e3af4235e4be.camel@adam-barratt.org.uk>
and subject line Closing p-u requests for updates in 11.3
has caused the Debian Bug report #1005340,
regarding bullseye-pu: package golang-1.15/1.15.15-1~deb11u3
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.)


-- 
1005340: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1005340
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: zhsj@debian.org, team@security.debian.org

[ Reason ]
Backport patches for CVE-2022-23806 CVE-2022-23772 CVE-2022-23773

[ Impact ]

+ CVE-2022-23806: crypto/elliptic: fix IsOnCurve for big.Int values
  that are not valid coordinates
+ CVE-2022-23772: math/big: prevent large memory consumption in
  Rat.SetString
+ CVE-2022-23773: cmd/go: prevent branches from materializing into versions

All are minor security issues, so I'd like to go with stable-pu.

[ Tests ]

For CVE-2022-23806 and CVE-2022-23772, regression tests are backported as well.

For CVE-2022-23773 the tests in upstream patch are hard to backport, so I test
it manully. The test is similar with upstream patch[1]

[1] https://github.com/golang/go/commit/fa4d9b8e2bc2612960c80474fca83a4c85a974eb#diff-6d41824e441b8846a74c31ab4968dc114a1e650c05172e1f89826ea9e55d4c5aR421

For example, running

  GOPROXY=direct /usr/lib/go-1.15/bin/go get vcs-test.golang.org/git/semver-branch.git@v1.0.0

Will get same result and error in [1].

[ Risks ]

Patch for CVE-2022-23806 and CVE-2022-23772 are trivial and easy to review.
Patch for CVE-2022-23773 is larger, and is backported by 3way merge.

[ 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 (old)stable
  [ ] the issue is verified as fixed in unstable
      golang-1.15 has been removed from unstable.

[ Changes ]

See attachment.

[ Other info ]

CVE-2022-23806 and CVE-2022-23772 are for Go std library, which is statically
linked in all Go programs. But these issues look like too minor to rebuild all
Go programs.
diff -Nru golang-1.15-1.15.15/debian/changelog golang-1.15-1.15.15/debian/changelog
--- golang-1.15-1.15.15/debian/changelog	2021-12-04 17:37:57.000000000 +0800
+++ golang-1.15-1.15.15/debian/changelog	2022-02-11 23:45:44.000000000 +0800
@@ -1,3 +1,14 @@
+golang-1.15 (1.15.15-1~deb11u3) bullseye; urgency=medium
+
+  * Backport patches for CVE-2022-23806 CVE-2022-23772 CVE-2022-23773
+    + CVE-2022-23806: crypto/elliptic: fix IsOnCurve for big.Int values
+      that are not valid coordinates
+    + CVE-2022-23772: math/big: prevent large memory consumption in
+      Rat.SetString
+    + CVE-2022-23773: cmd/go: prevent branches from materializing into versions
+
+ -- Shengjing Zhu <zhsj@debian.org>  Fri, 11 Feb 2022 23:45:44 +0800
+
 golang-1.15 (1.15.15-1~deb11u2) bullseye; urgency=medium
 
   * Backport patch for CVE-2021-38297
diff -Nru golang-1.15-1.15.15/debian/patches/0012-CVE-2022-23806.patch golang-1.15-1.15.15/debian/patches/0012-CVE-2022-23806.patch
--- golang-1.15-1.15.15/debian/patches/0012-CVE-2022-23806.patch	1970-01-01 08:00:00.000000000 +0800
+++ golang-1.15-1.15.15/debian/patches/0012-CVE-2022-23806.patch	2022-02-11 23:45:44.000000000 +0800
@@ -0,0 +1,132 @@
+From: Filippo Valsorda <filippo@golang.org>
+Date: Wed, 2 Feb 2022 09:15:44 -0800
+Subject: CVE-2022-23806
+
+Origin: backport, https://github.com/golang/go/commit/6b3e741a
+---
+ src/crypto/elliptic/elliptic.go      |  5 +++
+ src/crypto/elliptic/elliptic_test.go | 81 ++++++++++++++++++++++++++++++++++++
+ src/crypto/elliptic/p224.go          |  5 +++
+ 3 files changed, 91 insertions(+)
+
+diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
+index f93dc16..afedf18 100644
+--- a/src/crypto/elliptic/elliptic.go
++++ b/src/crypto/elliptic/elliptic.go
+@@ -71,6 +71,11 @@ func (curve *CurveParams) polynomial(x *big.Int) *big.Int {
+ }
+ 
+ func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
++	if x.Sign() < 0 || x.Cmp(curve.P) >= 0 ||
++		y.Sign() < 0 || y.Cmp(curve.P) >= 0 {
++		return false
++	}
++
+ 	// y² = x³ - 3x + b
+ 	y2 := new(big.Int).Mul(y, y)
+ 	y2.Mod(y2, curve.P)
+diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go
+index e80e773..bb16b0d 100644
+--- a/src/crypto/elliptic/elliptic_test.go
++++ b/src/crypto/elliptic/elliptic_test.go
+@@ -721,3 +721,84 @@ func testMarshalCompressed(t *testing.T, curve Curve, x, y *big.Int, want []byte
+ 		t.Errorf("point did not round-trip correctly: got (%v, %v), want (%v, %v)", X, Y, x, y)
+ 	}
+ }
++
++func testAllCurves(t *testing.T, f func(*testing.T, Curve)) {
++	tests := []struct {
++		name  string
++		curve Curve
++	}{
++		{"P256", P256()},
++		{"P256/Params", P256().Params()},
++		{"P224", P224()},
++		{"P224/Params", P224().Params()},
++		{"P384", P384()},
++		{"P384/Params", P384().Params()},
++		{"P521", P521()},
++		{"P521/Params", P521().Params()},
++	}
++	if testing.Short() {
++		tests = tests[:1]
++	}
++	for _, test := range tests {
++		curve := test.curve
++		t.Run(test.name, func(t *testing.T) {
++			t.Parallel()
++			f(t, curve)
++		})
++	}
++}
++
++// TestInvalidCoordinates tests big.Int values that are not valid field elements
++// (negative or bigger than P). They are expected to return false from
++// IsOnCurve, all other behavior is undefined.
++func TestInvalidCoordinates(t *testing.T) {
++	testAllCurves(t, testInvalidCoordinates)
++}
++
++func testInvalidCoordinates(t *testing.T, curve Curve) {
++	checkIsOnCurveFalse := func(name string, x, y *big.Int) {
++		if curve.IsOnCurve(x, y) {
++			t.Errorf("IsOnCurve(%s) unexpectedly returned true", name)
++		}
++	}
++
++	p := curve.Params().P
++	_, x, y, _ := GenerateKey(curve, rand.Reader)
++	xx, yy := new(big.Int), new(big.Int)
++
++	// Check if the sign is getting dropped.
++	xx.Neg(x)
++	checkIsOnCurveFalse("-x, y", xx, y)
++	yy.Neg(y)
++	checkIsOnCurveFalse("x, -y", x, yy)
++
++	// Check if negative values are reduced modulo P.
++	xx.Sub(x, p)
++	checkIsOnCurveFalse("x-P, y", xx, y)
++	yy.Sub(y, p)
++	checkIsOnCurveFalse("x, y-P", x, yy)
++
++	// Check if positive values are reduced modulo P.
++	xx.Add(x, p)
++	checkIsOnCurveFalse("x+P, y", xx, y)
++	yy.Add(y, p)
++	checkIsOnCurveFalse("x, y+P", x, yy)
++
++	// Check if the overflow is dropped.
++	xx.Add(x, new(big.Int).Lsh(big.NewInt(1), 535))
++	checkIsOnCurveFalse("x+2⁵³⁵, y", xx, y)
++	yy.Add(y, new(big.Int).Lsh(big.NewInt(1), 535))
++	checkIsOnCurveFalse("x, y+2⁵³⁵", x, yy)
++
++	// Check if P is treated like zero (if possible).
++	// y^2 = x^3 - 3x + B
++	// y = mod_sqrt(x^3 - 3x + B)
++	// y = mod_sqrt(B) if x = 0
++	// If there is no modsqrt, there is no point with x = 0, can't test x = P.
++	if yy := new(big.Int).ModSqrt(curve.Params().B, p); yy != nil {
++		if !curve.IsOnCurve(big.NewInt(0), yy) {
++			t.Fatal("(0, mod_sqrt(B)) is not on the curve?")
++		}
++		checkIsOnCurveFalse("P, y", p, yy)
++	}
++}
+diff --git a/src/crypto/elliptic/p224.go b/src/crypto/elliptic/p224.go
+index 8c76021..ff5c834 100644
+--- a/src/crypto/elliptic/p224.go
++++ b/src/crypto/elliptic/p224.go
+@@ -48,6 +48,11 @@ func (curve p224Curve) Params() *CurveParams {
+ }
+ 
+ func (curve p224Curve) IsOnCurve(bigX, bigY *big.Int) bool {
++	if bigX.Sign() < 0 || bigX.Cmp(curve.P) >= 0 ||
++		bigY.Sign() < 0 || bigY.Cmp(curve.P) >= 0 {
++		return false
++	}
++
+ 	var x, y p224FieldElement
+ 	p224FromBig(&x, bigX)
+ 	p224FromBig(&y, bigY)
diff -Nru golang-1.15-1.15.15/debian/patches/0013-CVE-2022-23772.patch golang-1.15-1.15.15/debian/patches/0013-CVE-2022-23772.patch
--- golang-1.15-1.15.15/debian/patches/0013-CVE-2022-23772.patch	1970-01-01 08:00:00.000000000 +0800
+++ golang-1.15-1.15.15/debian/patches/0013-CVE-2022-23772.patch	2022-02-11 23:45:44.000000000 +0800
@@ -0,0 +1,38 @@
+From: Katie Hockman <katie@golang.org>
+Date: Wed, 19 Jan 2022 16:54:41 -0500
+Subject: CVE-2022-23772
+
+Origin: backport, https://github.com/golang/go/commit/07ee9e64
+---
+ src/math/big/ratconv.go      | 5 +++++
+ src/math/big/ratconv_test.go | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
+index ac3c8bd..90053a9 100644
+--- a/src/math/big/ratconv.go
++++ b/src/math/big/ratconv.go
+@@ -169,6 +169,11 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
+ 		n := exp5
+ 		if n < 0 {
+ 			n = -n
++			if n < 0 {
++				// This can occur if -n overflows. -(-1 << 63) would become
++				// -1 << 63, which is still negative.
++				return nil, false
++			}
+ 		}
+ 		if n > 1e6 {
+ 			return nil, false // avoid excessively large exponents
+diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go
+index 15d206c..e55e655 100644
+--- a/src/math/big/ratconv_test.go
++++ b/src/math/big/ratconv_test.go
+@@ -104,6 +104,7 @@ var setStringTests = []StringTest{
+ 	{in: "4/3/"},
+ 	{in: "4/3."},
+ 	{in: "4/"},
++	{in: "13e-9223372036854775808"}, // CVE-2022-23772
+ 
+ 	// valid
+ 	{"0", "0", true},
diff -Nru golang-1.15-1.15.15/debian/patches/0014-CVE-2022-23773.patch golang-1.15-1.15.15/debian/patches/0014-CVE-2022-23773.patch
--- golang-1.15-1.15.15/debian/patches/0014-CVE-2022-23773.patch	1970-01-01 08:00:00.000000000 +0800
+++ golang-1.15-1.15.15/debian/patches/0014-CVE-2022-23773.patch	2022-02-11 23:45:44.000000000 +0800
@@ -0,0 +1,323 @@
+From: "Bryan C. Mills" <bcmills@google.com>
+Date: Thu, 13 Jan 2022 15:38:14 -0500
+Subject: CVE-2022-23773
+
+Origin: backport, https://github.com/golang/go/commit/de76489a
+
+Only change in coderep.go is backported. Changes in coderepo_test.go
+and mod_invalid_version.txt are used for testing, which can't be
+cherry-picked directly.
+---
+ src/cmd/go/internal/modfetch/coderepo.go | 215 +++++++++++++++----------------
+ 1 file changed, 106 insertions(+), 109 deletions(-)
+
+diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
+index d043903..3297af9 100644
+--- a/src/cmd/go/internal/modfetch/coderepo.go
++++ b/src/cmd/go/internal/modfetch/coderepo.go
+@@ -298,16 +298,13 @@ func (r *codeRepo) Latest() (*RevInfo, error) {
+ // If statVers is a valid module version, it is used for the Version field.
+ // Otherwise, the Version is derived from the passed-in info and recent tags.
+ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, error) {
+-	info2 := &RevInfo{
+-		Name:  info.Name,
+-		Short: info.Short,
+-		Time:  info.Time,
+-	}
+-
+ 	// If this is a plain tag (no dir/ prefix)
+ 	// and the module path is unversioned,
+ 	// and if the underlying file tree has no go.mod,
+ 	// then allow using the tag with a +incompatible suffix.
++	//
++	// (If the version is +incompatible, then the go.mod file must not exist:
++	// +incompatible is not an ongoing opt-out from semantic import versioning.)
+ 	var canUseIncompatible func() bool
+ 	canUseIncompatible = func() bool {
+ 		var ok bool
+@@ -321,19 +318,12 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
+ 		return ok
+ 	}
+ 
+-	invalidf := func(format string, args ...interface{}) error {
+-		return &module.ModuleError{
+-			Path: r.modPath,
+-			Err: &module.InvalidVersionError{
+-				Version: info2.Version,
+-				Err:     fmt.Errorf(format, args...),
+-			},
+-		}
+-	}
+-
+-	// checkGoMod verifies that the go.mod file for the module exists or does not
+-	// exist as required by info2.Version and the module path represented by r.
+-	checkGoMod := func() (*RevInfo, error) {
++	// checkCanonical verifies that the canonical version v is compatible with the
++	// module path represented by r, adding a "+incompatible" suffix if needed.
++	//
++	// If statVers is also canonical, checkCanonical also verifies that v is
++	// either statVers or statVers with the added "+incompatible" suffix.
++	checkCanonical := func(v string) (*RevInfo, error) {
+ 		// If r.codeDir is non-empty, then the go.mod file must exist: the module
+ 		// author — not the module consumer, — gets to decide how to carve up the repo
+ 		// into modules.
+@@ -344,73 +334,91 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
+ 		// r.findDir verifies both of these conditions. Execute it now so that
+ 		// r.Stat will correctly return a notExistError if the go.mod location or
+ 		// declared module path doesn't match.
+-		_, _, _, err := r.findDir(info2.Version)
++		_, _, _, err := r.findDir(v)
+ 		if err != nil {
+ 			// TODO: It would be nice to return an error like "not a module".
+ 			// Right now we return "missing go.mod", which is a little confusing.
+ 			return nil, &module.ModuleError{
+ 				Path: r.modPath,
+ 				Err: &module.InvalidVersionError{
+-					Version: info2.Version,
++					Version: v,
+ 					Err:     notExistError{err: err},
+ 				},
+ 			}
+ 		}
+ 
+-		// If the version is +incompatible, then the go.mod file must not exist:
+-		// +incompatible is not an ongoing opt-out from semantic import versioning.
+-		if strings.HasSuffix(info2.Version, "+incompatible") {
+-			if !canUseIncompatible() {
++		invalidf := func(format string, args ...interface{}) error {
++			return &module.ModuleError{
++				Path: r.modPath,
++				Err: &module.InvalidVersionError{
++					Version: v,
++					Err:     fmt.Errorf(format, args...),
++				},
++			}
++		}
++
++		// Add the +incompatible suffix if needed or requested explicitly, and
++		// verify that its presence or absence is appropriate for this version
++		// (which depends on whether it has an explicit go.mod file).
++
++		if v == strings.TrimSuffix(statVers, "+incompatible") {
++			v = statVers
++		}
++		base := strings.TrimSuffix(v, "+incompatible")
++		var errIncompatible error
++		if !module.MatchPathMajor(base, r.pathMajor) {
++			if canUseIncompatible() {
++				v = base + "+incompatible"
++			} else {
+ 				if r.pathMajor != "" {
+-					return nil, invalidf("+incompatible suffix not allowed: module path includes a major version suffix, so major version must match")
++					errIncompatible = invalidf("module path includes a major version suffix, so major version must match")
+ 				} else {
+-					return nil, invalidf("+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required")
++					errIncompatible = invalidf("module contains a go.mod file, so module path must match major version (%q)", path.Join(r.pathPrefix, semver.Major(v)))
+ 				}
+ 			}
+-
+-			if err := module.CheckPathMajor(strings.TrimSuffix(info2.Version, "+incompatible"), r.pathMajor); err == nil {
+-				return nil, invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(info2.Version))
++		} else if strings.HasSuffix(v, "+incompatible") {
++			errIncompatible = invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(v))
++		}
++
++		if statVers != "" && statVers == module.CanonicalVersion(statVers) {
++			// Since the caller-requested version is canonical, it would be very
++			// confusing to resolve it to anything but itself, possibly with a
++			// "+incompatible" suffix. Error out explicitly.
++			if statBase := strings.TrimSuffix(statVers, "+incompatible"); statBase != base {
++				return nil, &module.ModuleError{
++					Path: r.modPath,
++					Err: &module.InvalidVersionError{
++						Version: statVers,
++						Err:     fmt.Errorf("resolves to version %v (%s is not a tag)", v, statBase),
++					},
++				}
+ 			}
+ 		}
+ 
+-		return info2, nil
++		if errIncompatible != nil {
++			return nil, errIncompatible
++		}
++
++		return &RevInfo{
++			Name:    info.Name,
++			Short:   info.Short,
++			Time:    info.Time,
++			Version: v,
++		}, nil
+ 	}
+ 
+ 	// Determine version.
+-	//
+-	// If statVers is canonical, then the original call was repo.Stat(statVers).
+-	// Since the version is canonical, we must not resolve it to anything but
+-	// itself, possibly with a '+incompatible' annotation: we do not need to do
+-	// the work required to look for an arbitrary pseudo-version.
+-	if statVers != "" && statVers == module.CanonicalVersion(statVers) {
+-		info2.Version = statVers
+-
+-		if IsPseudoVersion(info2.Version) {
+-			if err := r.validatePseudoVersion(info, info2.Version); err != nil {
+-				return nil, err
+-			}
+-			return checkGoMod()
+-		}
+ 
+-		if err := module.CheckPathMajor(info2.Version, r.pathMajor); err != nil {
+-			if canUseIncompatible() {
+-				info2.Version += "+incompatible"
+-				return checkGoMod()
+-			} else {
+-				if vErr, ok := err.(*module.InvalidVersionError); ok {
+-					// We're going to describe why the version is invalid in more detail,
+-					// so strip out the existing “invalid version” wrapper.
+-					err = vErr.Err
+-				}
+-				return nil, invalidf("module contains a go.mod file, so major version must be compatible: %v", err)
+-			}
++	if IsPseudoVersion(statVers) {
++		if err := r.validatePseudoVersion(info, statVers); err != nil {
++			return nil, err
+ 		}
+-
+-		return checkGoMod()
++		return checkCanonical(statVers)
+ 	}
+ 
+-	// statVers is empty or non-canonical, so we need to resolve it to a canonical
+-	// version or pseudo-version.
++	// statVers is not a pseudo-version, so we need to either resolve it to a
++	// canonical version or verify that it is already a canonical tag
++	// (not a branch).
+ 
+ 	// Derive or verify a version from a code repo tag.
+ 	// Tag must have a prefix matching codeDir.
+@@ -439,65 +447,59 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
+ 		if v == trimmed {
+ 			tagIsCanonical = true
+ 		}
+-
+-		if err := module.CheckPathMajor(v, r.pathMajor); err != nil {
+-			if canUseIncompatible() {
+-				return v + "+incompatible", tagIsCanonical
+-			}
+-			return "", false
+-		}
+-
+ 		return v, tagIsCanonical
+ 	}
+ 
+ 	// If the VCS gave us a valid version, use that.
+ 	if v, tagIsCanonical := tagToVersion(info.Version); tagIsCanonical {
+-		info2.Version = v
+-		return checkGoMod()
++		if info, err := checkCanonical(v); err == nil {
++			return info, err
++		}
+ 	}
+ 
+ 	// Look through the tags on the revision for either a usable canonical version
+ 	// or an appropriate base for a pseudo-version.
+-	var pseudoBase string
++	var (
++		highestCanonical string
++		pseudoBase       string
++	)
+ 	for _, pathTag := range info.Tags {
+ 		v, tagIsCanonical := tagToVersion(pathTag)
+-		if tagIsCanonical {
+-			if statVers != "" && semver.Compare(v, statVers) == 0 {
+-				// The user requested a non-canonical version, but the tag for the
+-				// canonical equivalent refers to the same revision. Use it.
+-				info2.Version = v
+-				return checkGoMod()
++		if statVers != "" && semver.Compare(v, statVers) == 0 {
++			// The tag is equivalent to the version requested by the user.
++			if tagIsCanonical {
++				// This tag is the canonical form of the requested version,
++				// not some other form with extra build metadata.
++				// Use this tag so that the resolved version will match exactly.
++				// (If it isn't actually allowed, we'll error out in checkCanonical.)
++				return checkCanonical(v)
+ 			} else {
+-				// Save the highest canonical tag for the revision. If we don't find a
+-				// better match, we'll use it as the canonical version.
++				// The user explicitly requested something equivalent to this tag. We
++				// can't use the version from the tag directly: since the tag is not
++				// canonical, it could be ambiguous. For example, tags v0.0.1+a and
++				// v0.0.1+b might both exist and refer to different revisions.
+ 				//
+-				// NOTE: Do not replace this with semver.Max. Despite the name,
+-				// semver.Max *also* canonicalizes its arguments, which uses
+-				// semver.Canonical instead of module.CanonicalVersion and thereby
+-				// strips our "+incompatible" suffix.
+-				if semver.Compare(info2.Version, v) < 0 {
+-					info2.Version = v
+-				}
++				// The tag is otherwise valid for the module, so we can at least use it as
++				// the base of an unambiguous pseudo-version.
++				//
++				// If multiple tags match, tagToVersion will canonicalize them to the same
++				// base version.
++				pseudoBase = v
++			}
++		}
++		// Save the highest non-retracted canonical tag for the revision.
++		// If we don't find a better match, we'll use it as the canonical version.
++		if tagIsCanonical && semver.Compare(highestCanonical, v) < 0 {
++			if module.MatchPathMajor(v, r.pathMajor) || canUseIncompatible() {
++				highestCanonical = v
+ 			}
+-		} else if v != "" && semver.Compare(v, statVers) == 0 {
+-			// The user explicitly requested something equivalent to this tag. We
+-			// can't use the version from the tag directly: since the tag is not
+-			// canonical, it could be ambiguous. For example, tags v0.0.1+a and
+-			// v0.0.1+b might both exist and refer to different revisions.
+-			//
+-			// The tag is otherwise valid for the module, so we can at least use it as
+-			// the base of an unambiguous pseudo-version.
+-			//
+-			// If multiple tags match, tagToVersion will canonicalize them to the same
+-			// base version.
+-			pseudoBase = v
+ 		}
+ 	}
+ 
+-	// If we found any canonical tag for the revision, return it.
++	// If we found a valid canonical tag for the revision, return it.
+ 	// Even if we found a good pseudo-version base, a canonical version is better.
+-	if info2.Version != "" {
+-		return checkGoMod()
++	if highestCanonical != "" {
++		return checkCanonical(highestCanonical)
+ 	}
+ 
+ 	if pseudoBase == "" {
+@@ -511,11 +513,10 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
+ 				tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v0")
+ 			}
+ 		}
+-		pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
++		pseudoBase, _ = tagToVersion(tag)
+ 	}
+ 
+-	info2.Version = PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
+-	return checkGoMod()
++	return checkCanonical(PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short))
+ }
+ 
+ // validatePseudoVersion checks that version has a major version compatible with
+@@ -539,10 +540,6 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
+ 		}
+ 	}()
+ 
+-	if err := module.CheckPathMajor(version, r.pathMajor); err != nil {
+-		return err
+-	}
+-
+ 	rev, err := PseudoVersionRev(version)
+ 	if err != nil {
+ 		return err
diff -Nru golang-1.15-1.15.15/debian/patches/series golang-1.15-1.15.15/debian/patches/series
--- golang-1.15-1.15.15/debian/patches/series	2021-12-04 17:37:57.000000000 +0800
+++ golang-1.15-1.15.15/debian/patches/series	2022-02-11 23:45:44.000000000 +0800
@@ -9,3 +9,6 @@
 0009-CVE-2021-41771.patch
 0010-CVE-2021-44716.patch
 0011-CVE-2021-44717.patch
+0012-CVE-2022-23806.patch
+0013-CVE-2022-23772.patch
+0014-CVE-2022-23773.patch

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 11.3

Hi,

The updates referenced by these bugs were included in stable as part of
this morning's 11.3 point release.

Regards,

Adam

--- End Message ---

Reply to: