From: Hitendra Prajapati <hprajap...@mvista.com>

Source: https://go-review.googlesource.com/c/go
MR: 117551
Type: Security Fix
Disposition: Backport from https://go-review.googlesource.com/c/go/+/399816/
ChangeID: 347f22f93e8eaecb3d39f8d6c0fe5a70c5cf7b7c
Description:
        CVE-2022-24675 golang: encoding/pem: fix stack overflow in Decode.

Signed-off-by: Hitendra Prajapati <hprajap...@mvista.com>
Signed-off-by: Steve Sakoman <st...@sakoman.com>
---
 meta/recipes-devtools/go/go-1.14.inc          |   1 +
 .../go/go-1.14/CVE-2022-24675.patch           | 271 ++++++++++++++++++
 2 files changed, 272 insertions(+)
 create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2022-24675.patch

diff --git a/meta/recipes-devtools/go/go-1.14.inc 
b/meta/recipes-devtools/go/go-1.14.inc
index 4827c6adfa..773d252bd1 100644
--- a/meta/recipes-devtools/go/go-1.14.inc
+++ b/meta/recipes-devtools/go/go-1.14.inc
@@ -23,6 +23,7 @@ SRC_URI += "\
     file://CVE-2022-23806.patch \
     file://CVE-2022-23772.patch \
     file://CVE-2021-44717.patch \
+    file://CVE-2022-24675.patch \
 "
 
 SRC_URI_append_libc-musl = " 
file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2022-24675.patch 
b/meta/recipes-devtools/go/go-1.14/CVE-2022-24675.patch
new file mode 100644
index 0000000000..4bc012be21
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2022-24675.patch
@@ -0,0 +1,271 @@
+From 1eb931d60a24501a9668e5cb4647593e19115507 Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajap...@mvista.com>
+Date: Fri, 17 Jun 2022 12:22:53 +0530
+Subject: [PATCH] CVE-2022-24675
+
+Upstream-Status: Backport [https://go-review.googlesource.com/c/go/+/399816/]
+CVE: CVE-2022-24675
+Signed-off-by: Hitendra Prajapati <hprajap...@mvista.com>
+---
+ src/encoding/pem/pem.go      | 174 +++++++++++++++--------------------
+ src/encoding/pem/pem_test.go |  28 +++++-
+ 2 files changed, 101 insertions(+), 101 deletions(-)
+
+diff --git a/src/encoding/pem/pem.go b/src/encoding/pem/pem.go
+index a7272da..1bee1c1 100644
+--- a/src/encoding/pem/pem.go
++++ b/src/encoding/pem/pem.go
+@@ -87,123 +87,97 @@ func Decode(data []byte) (p *Block, rest []byte) {
+       // pemStart begins with a newline. However, at the very beginning of
+       // the byte array, we'll accept the start string without it.
+       rest = data
+-      if bytes.HasPrefix(data, pemStart[1:]) {
+-              rest = rest[len(pemStart)-1 : len(data)]
+-      } else if i := bytes.Index(data, pemStart); i >= 0 {
+-              rest = rest[i+len(pemStart) : len(data)]
+-      } else {
+-              return nil, data
+-      }
+-
+-      typeLine, rest := getLine(rest)
+-      if !bytes.HasSuffix(typeLine, pemEndOfLine) {
+-              return decodeError(data, rest)
+-      }
+-      typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
+-
+-      p = &Block{
+-              Headers: make(map[string]string),
+-              Type:    string(typeLine),
+-      }
+-
+       for {
+-              // This loop terminates because getLine's second result is
+-              // always smaller than its argument.
+-              if len(rest) == 0 {
++              if bytes.HasPrefix(rest, pemStart[1:]) {
++                      rest = rest[len(pemStart)-1:]
++              } else if i := bytes.Index(rest, pemStart); i >= 0 {
++                      rest = rest[i+len(pemStart) : len(rest)]
++              } else {
+                       return nil, data
+               }
+-              line, next := getLine(rest)
+ 
+-              i := bytes.IndexByte(line, ':')
+-              if i == -1 {
+-                      break
++              var typeLine []byte
++              typeLine, rest = getLine(rest)
++              if !bytes.HasSuffix(typeLine, pemEndOfLine) {
++                      continue
+               }
++              typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
+ 
+-              // TODO(agl): need to cope with values that spread across lines.
+-              key, val := line[:i], line[i+1:]
+-              key = bytes.TrimSpace(key)
+-              val = bytes.TrimSpace(val)
+-              p.Headers[string(key)] = string(val)
+-              rest = next
+-      }
++              p = &Block{
++                      Headers: make(map[string]string),
++                      Type:    string(typeLine),
++              }
+ 
+-      var endIndex, endTrailerIndex int
++              for {
++                      // This loop terminates because getLine's second result 
is
++                      // always smaller than its argument.
++                      if len(rest) == 0 {
++                              return nil, data
++                      }
++                      line, next := getLine(rest)
+ 
+-      // If there were no headers, the END line might occur
+-      // immediately, without a leading newline.
+-      if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
+-              endIndex = 0
+-              endTrailerIndex = len(pemEnd) - 1
+-      } else {
+-              endIndex = bytes.Index(rest, pemEnd)
+-              endTrailerIndex = endIndex + len(pemEnd)
+-      }
++                      i := bytes.IndexByte(line, ':')
++                      if i == -1 {
++                              break
++                      }
+ 
+-      if endIndex < 0 {
+-              return decodeError(data, rest)
+-      }
++                      // TODO(agl): need to cope with values that spread 
across lines.
++                      key, val := line[:i], line[i+1:]
++                      key = bytes.TrimSpace(key)
++                      val = bytes.TrimSpace(val)
++                      p.Headers[string(key)] = string(val)
++                      rest = next
++              }
+ 
+-      // After the "-----" of the ending line, there should be the same type
+-      // and then a final five dashes.
+-      endTrailer := rest[endTrailerIndex:]
+-      endTrailerLen := len(typeLine) + len(pemEndOfLine)
+-      if len(endTrailer) < endTrailerLen {
+-              return decodeError(data, rest)
+-      }
++              var endIndex, endTrailerIndex int
+ 
+-      restOfEndLine := endTrailer[endTrailerLen:]
+-      endTrailer = endTrailer[:endTrailerLen]
+-      if !bytes.HasPrefix(endTrailer, typeLine) ||
+-              !bytes.HasSuffix(endTrailer, pemEndOfLine) {
+-              return decodeError(data, rest)
+-      }
++              // If there were no headers, the END line might occur
++              // immediately, without a leading newline.
++              if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
++                      endIndex = 0
++                      endTrailerIndex = len(pemEnd) - 1
++              } else {
++                      endIndex = bytes.Index(rest, pemEnd)
++                      endTrailerIndex = endIndex + len(pemEnd)
++              }
+ 
+-      // The line must end with only whitespace.
+-      if s, _ := getLine(restOfEndLine); len(s) != 0 {
+-              return decodeError(data, rest)
+-      }
++              if endIndex < 0 {
++                      continue
++              }
+ 
+-      base64Data := removeSpacesAndTabs(rest[:endIndex])
+-      p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
+-      n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
+-      if err != nil {
+-              return decodeError(data, rest)
+-      }
+-      p.Bytes = p.Bytes[:n]
++              // After the "-----" of the ending line, there should be the 
same type
++              // and then a final five dashes.
++              endTrailer := rest[endTrailerIndex:]
++              endTrailerLen := len(typeLine) + len(pemEndOfLine)
++              if len(endTrailer) < endTrailerLen {
++                      continue
++              }
++
++              restOfEndLine := endTrailer[endTrailerLen:]
++              endTrailer = endTrailer[:endTrailerLen]
++              if !bytes.HasPrefix(endTrailer, typeLine) ||
++                      !bytes.HasSuffix(endTrailer, pemEndOfLine) {
++                      continue
++              }
+ 
+-      // the -1 is because we might have only matched pemEnd without the
+-      // leading newline if the PEM block was empty.
+-      _, rest = getLine(rest[endIndex+len(pemEnd)-1:])
++              // The line must end with only whitespace.
++              if s, _ := getLine(restOfEndLine); len(s) != 0 {
++                      continue
++              }
+ 
+-      return
+-}
++              base64Data := removeSpacesAndTabs(rest[:endIndex])
++              p.Bytes = make([]byte, 
base64.StdEncoding.DecodedLen(len(base64Data)))
++              n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
++              if err != nil {
++                      continue
++              }
++              p.Bytes = p.Bytes[:n]
+ 
+-func decodeError(data, rest []byte) (*Block, []byte) {
+-      // If we get here then we have rejected a likely looking, but
+-      // ultimately invalid PEM block. We need to start over from a new
+-      // position. We have consumed the preamble line and will have consumed
+-      // any lines which could be header lines. However, a valid preamble
+-      // line is not a valid header line, therefore we cannot have consumed
+-      // the preamble line for the any subsequent block. Thus, we will always
+-      // find any valid block, no matter what bytes precede it.
+-      //
+-      // For example, if the input is
+-      //
+-      //    -----BEGIN MALFORMED BLOCK-----
+-      //    junk that may look like header lines
+-      //   or data lines, but no END line
+-      //
+-      //    -----BEGIN ACTUAL BLOCK-----
+-      //    realdata
+-      //    -----END ACTUAL BLOCK-----
+-      //
+-      // we've failed to parse using the first BEGIN line
+-      // and now will try again, using the second BEGIN line.
+-      p, rest := Decode(rest)
+-      if p == nil {
+-              rest = data
++              // the -1 is because we might have only matched pemEnd without 
the
++              // leading newline if the PEM block was empty.
++              _, rest = getLine(rest[endIndex+len(pemEnd)-1:])
++              return p, rest
+       }
+-      return p, rest
+ }
+ 
+ const pemLineLength = 64
+diff --git a/src/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go
+index 8515b46..4485581 100644
+--- a/src/encoding/pem/pem_test.go
++++ b/src/encoding/pem/pem_test.go
+@@ -107,6 +107,12 @@ const pemMissingEndingSpace = `
+ dGVzdA==
+ -----ENDBAR-----`
+ 
++const pemMissingEndLine = `
++-----BEGIN FOO-----
++Header: 1`
++
++var pemRepeatingBegin = strings.Repeat("-----BEGIN \n", 10)
++
+ var badPEMTests = []struct {
+       name  string
+       input string
+@@ -131,14 +137,34 @@ var badPEMTests = []struct {
+               "missing ending space",
+               pemMissingEndingSpace,
+       },
++      {
++              "repeating begin",
++              pemRepeatingBegin,
++      },
++      {
++              "missing end line",
++              pemMissingEndLine,
++      },
+ }
+ 
+ func TestBadDecode(t *testing.T) {
+       for _, test := range badPEMTests {
+-              result, _ := Decode([]byte(test.input))
++              result, rest := Decode([]byte(test.input))
+               if result != nil {
+                       t.Errorf("unexpected success while parsing %q", 
test.name)
+               }
++              if string(rest) != test.input {
++                      t.Errorf("unexpected rest: %q; want = %q", rest, 
test.input)
++              }
++      }
++}
++
++func TestCVE202224675(t *testing.T) {
++      // Prior to CVE-2022-24675, this input would cause a stack overflow.
++      input := []byte(strings.Repeat("-----BEGIN \n", 10000000))
++      result, rest := Decode(input)
++      if result != nil || !reflect.DeepEqual(rest, input) {
++              t.Errorf("Encode of %#v decoded as %#v", input, rest)
+       }
+ }
+ 
+-- 
+2.25.1
+
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#167417): 
https://lists.openembedded.org/g/openembedded-core/message/167417
Mute This Topic: https://lists.openembedded.org/mt/92090257/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to