diff --git a/Dockerfile b/Dockerfile index 717a2a4789..9472c512a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG CROSS="false" ARG SYSTEMD="false" # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored -ARG GO_VERSION=1.18.6 +ARG GO_VERSION=1.18.7 ARG DEBIAN_FRONTEND=noninteractive ARG VPNKIT_VERSION=0.5.0 ARG DOCKER_BUILDTAGS="apparmor seccomp" diff --git a/Dockerfile.e2e b/Dockerfile.e2e index b7ad9786f9..f92bec85b0 100644 --- a/Dockerfile.e2e +++ b/Dockerfile.e2e @@ -1,4 +1,4 @@ -ARG GO_VERSION=1.18.6 +ARG GO_VERSION=1.18.7 FROM golang:${GO_VERSION}-alpine AS base ENV GO111MODULE=off diff --git a/Dockerfile.simple b/Dockerfile.simple index 196afc0566..8aa6d7ff94 100644 --- a/Dockerfile.simple +++ b/Dockerfile.simple @@ -5,7 +5,7 @@ # This represents the bare minimum required to build and test Docker. -ARG GO_VERSION=1.18.6 +ARG GO_VERSION=1.18.7 FROM golang:${GO_VERSION}-buster ENV GO111MODULE=off diff --git a/Dockerfile.windows b/Dockerfile.windows index e289a29cc2..6f8242decc 100644 --- a/Dockerfile.windows +++ b/Dockerfile.windows @@ -165,7 +165,7 @@ FROM microsoft/windowsservercore # Use PowerShell as the default shell SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] -ARG GO_VERSION=1.18.6 +ARG GO_VERSION=1.18.7 ARG GOTESTSUM_VERSION=v1.7.0 # Environment variable notes: diff --git a/vendor/archive/tar/format.go b/vendor/archive/tar/format.go index 21b9d9d4db..8898c438b5 100644 --- a/vendor/archive/tar/format.go +++ b/vendor/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/vendor/archive/tar/reader.go b/vendor/archive/tar/reader.go index 4b11909bc9..e609c15f27 100644 --- a/vendor/archive/tar/reader.go +++ b/vendor/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 } @@ -828,6 +828,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/vendor/archive/tar/reader_test.go b/vendor/archive/tar/reader_test.go index f21a6065b4..140c736429 100644 --- a/vendor/archive/tar/reader_test.go +++ b/vendor/archive/tar/reader_test.go @@ -6,6 +6,7 @@ package tar import ( "bytes" + "compress/bzip2" "crypto/md5" "errors" "fmt" @@ -243,6 +244,9 @@ func TestReader(t *testing.T) { }, { file: "testdata/pax-bad-hdr-file.tar", err: ErrHeader, + }, { + file: "testdata/pax-bad-hdr-large.tar.bz2", + err: ErrFieldTooLong, }, { file: "testdata/pax-bad-mtime-file.tar", err: ErrHeader, @@ -625,9 +629,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/vendor/archive/tar/testdata/pax-bad-hdr-large.tar.bz2 b/vendor/archive/tar/testdata/pax-bad-hdr-large.tar.bz2 new file mode 100644 index 0000000000..06bf710d3a Binary files /dev/null and b/vendor/archive/tar/testdata/pax-bad-hdr-large.tar.bz2 differ diff --git a/vendor/archive/tar/writer.go b/vendor/archive/tar/writer.go index 3729f7e82c..9b2e3e25d4 100644 --- a/vendor/archive/tar/writer.go +++ b/vendor/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/vendor/archive/tar/writer_test.go b/vendor/archive/tar/writer_test.go index da3fb89e65..640264984a 100644 --- a/vendor/archive/tar/writer_test.go +++ b/vendor/archive/tar/writer_test.go @@ -1004,6 +1004,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 }