--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: z...@debian.org, t...@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 <z...@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 <fili...@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 <ka...@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" <bcmi...@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 ---