summaryrefslogtreecommitdiff
path: root/poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch
diff options
context:
space:
mode:
Diffstat (limited to 'poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch')
-rw-r--r--poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch177
1 files changed, 177 insertions, 0 deletions
diff --git a/poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch b/poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch
new file mode 100644
index 0000000000..0315e1a3ee
--- /dev/null
+++ b/poky/meta/recipes-devtools/go/go-1.18/CVE-2022-2879.patch
@@ -0,0 +1,177 @@
+From d064ed520a7cc6b480f9565e30751e695d394f4e Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Fri, 2 Sep 2022 20:45:18 -0700
+Subject: [PATCH] archive/tar: limit size of headers
+
+Set a 1MiB limit on special file blocks (PAX headers, GNU long names,
+GNU link names), to avoid reading arbitrarily large amounts of data
+into memory.
+
+Thanks to Adam Korczynski (ADA Logics) and OSS-Fuzz for reporting
+this issue.
+
+Fixes CVE-2022-2879
+Updates #54853
+Fixes #55925
+
+Change-Id: I85136d6ff1e0af101a112190e027987ab4335680
+Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565555
+Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
+Run-TryBot: Roland Shoemaker <bracewell@google.com>
+Reviewed-by: Roland Shoemaker <bracewell@google.com>
+(cherry picked from commit 6ee768cef6b82adf7a90dcf367a1699ef694f3b2)
+Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1590622
+Reviewed-by: Damien Neil <dneil@google.com>
+Reviewed-by: Julie Qiu <julieqiu@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/438500
+Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
+Reviewed-by: Carlos Amedee <carlos@golang.org>
+Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
+Run-TryBot: Carlos Amedee <carlos@golang.org>
+TryBot-Result: Gopher Robot <gobot@golang.org>
+
+CVE: CVE-2022-2879
+Upstream-Status: Backport [0a723816cd205576945fa57fbdde7e6532d59d08]
+Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
+---
+ src/archive/tar/format.go | 4 ++++
+ src/archive/tar/reader.go | 14 ++++++++++++--
+ src/archive/tar/reader_test.go | 8 +++++++-
+ src/archive/tar/writer.go | 3 +++
+ src/archive/tar/writer_test.go | 27 +++++++++++++++++++++++++++
+ 5 files changed, 53 insertions(+), 3 deletions(-)
+
+diff --git a/src/archive/tar/format.go b/src/archive/tar/format.go
+index cfe24a5..6642364 100644
+--- a/src/archive/tar/format.go
++++ b/src/archive/tar/format.go
+@@ -143,6 +143,10 @@ const (
+ blockSize = 512 // Size of each block in a tar stream
+ nameSize = 100 // Max length of the name field in USTAR format
+ prefixSize = 155 // Max length of the prefix field in USTAR format
++
++ // Max length of a special file (PAX header, GNU long name or link).
++ // This matches the limit used by libarchive.
++ maxSpecialFileSize = 1 << 20
+ )
+
+ // blockPadding computes the number of bytes needed to pad offset up to the
+diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
+index 1b1d5b4..f645af8 100644
+--- a/src/archive/tar/reader.go
++++ b/src/archive/tar/reader.go
+@@ -103,7 +103,7 @@ func (tr *Reader) next() (*Header, error) {
+ continue // This is a meta header affecting the next header
+ case TypeGNULongName, TypeGNULongLink:
+ format.mayOnlyBe(FormatGNU)
+- realname, err := io.ReadAll(tr)
++ realname, err := readSpecialFile(tr)
+ if err != nil {
+ return nil, err
+ }
+@@ -293,7 +293,7 @@ func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
+ // parsePAX parses PAX headers.
+ // If an extended header (type 'x') is invalid, ErrHeader is returned
+ func parsePAX(r io.Reader) (map[string]string, error) {
+- buf, err := io.ReadAll(r)
++ buf, err := readSpecialFile(r)
+ if err != nil {
+ return nil, err
+ }
+@@ -826,6 +826,16 @@ func tryReadFull(r io.Reader, b []byte) (n int, err error) {
+ return n, err
+ }
+
++// readSpecialFile is like io.ReadAll except it returns
++// ErrFieldTooLong if more than maxSpecialFileSize is read.
++func readSpecialFile(r io.Reader) ([]byte, error) {
++ buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
++ if len(buf) > maxSpecialFileSize {
++ return nil, ErrFieldTooLong
++ }
++ return buf, err
++}
++
+ // discard skips n bytes in r, reporting an error if unable to do so.
+ func discard(r io.Reader, n int64) error {
+ // If possible, Seek to the last byte before the end of the data section.
+diff --git a/src/archive/tar/reader_test.go b/src/archive/tar/reader_test.go
+index 789ddc1..926dc3d 100644
+--- a/src/archive/tar/reader_test.go
++++ b/src/archive/tar/reader_test.go
+@@ -6,6 +6,7 @@ package tar
+
+ import (
+ "bytes"
++ "compress/bzip2"
+ "crypto/md5"
+ "errors"
+ "fmt"
+@@ -625,9 +626,14 @@ func TestReader(t *testing.T) {
+ }
+ defer f.Close()
+
++ var fr io.Reader = f
++ if strings.HasSuffix(v.file, ".bz2") {
++ fr = bzip2.NewReader(fr)
++ }
++
+ // Capture all headers and checksums.
+ var (
+- tr = NewReader(f)
++ tr = NewReader(fr)
+ hdrs []*Header
+ chksums []string
+ rdbuf = make([]byte, 8)
+diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go
+index e80498d..893eac0 100644
+--- a/src/archive/tar/writer.go
++++ b/src/archive/tar/writer.go
+@@ -199,6 +199,9 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
+ flag = TypeXHeader
+ }
+ data := buf.String()
++ if len(data) > maxSpecialFileSize {
++ return ErrFieldTooLong
++ }
+ if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {
+ return err // Global headers return here
+ }
+diff --git a/src/archive/tar/writer_test.go b/src/archive/tar/writer_test.go
+index a00f02d..4e709e5 100644
+--- a/src/archive/tar/writer_test.go
++++ b/src/archive/tar/writer_test.go
+@@ -1006,6 +1006,33 @@ func TestIssue12594(t *testing.T) {
+ }
+ }
+
++func TestWriteLongHeader(t *testing.T) {
++ for _, test := range []struct {
++ name string
++ h *Header
++ }{{
++ name: "name too long",
++ h: &Header{Name: strings.Repeat("a", maxSpecialFileSize)},
++ }, {
++ name: "linkname too long",
++ h: &Header{Linkname: strings.Repeat("a", maxSpecialFileSize)},
++ }, {
++ name: "uname too long",
++ h: &Header{Uname: strings.Repeat("a", maxSpecialFileSize)},
++ }, {
++ name: "gname too long",
++ h: &Header{Gname: strings.Repeat("a", maxSpecialFileSize)},
++ }, {
++ name: "PAX header too long",
++ h: &Header{PAXRecords: map[string]string{"GOLANG.x": strings.Repeat("a", maxSpecialFileSize)}},
++ }} {
++ w := NewWriter(io.Discard)
++ if err := w.WriteHeader(test.h); err != ErrFieldTooLong {
++ t.Errorf("%v: w.WriteHeader() = %v, want ErrFieldTooLong", test.name, err)
++ }
++ }
++}
++
+ // testNonEmptyWriter wraps an io.Writer and ensures that
+ // Write is never called with an empty buffer.
+ type testNonEmptyWriter struct{ io.Writer }