app-containers/containerd: Update spdystream to v0.5.1 Patch generated by setting spdystream version to 0.5.1 in go.mod and running `go mod tidy && go mod vendor && make vendor`. BUG=b/502611924 TEST=presubmit RELEASE_NOTE=Updated spdystream to v0.5.1 for containerd. This fixed CVE-2026-35469. cos-patch: security-high Change-Id: I430ed66bde209ab1b83683039a22d1ce29eb939a Reviewed-on: https://cos-review.googlesource.com/c/cos/overlays/board-overlays/+/144194 Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com> Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com> Main-Branch-Verified: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
diff --git a/project-lakitu/app-containers/containerd/containerd-1.7.27-r2.ebuild b/project-lakitu/app-containers/containerd/containerd-1.7.27-r3.ebuild similarity index 100% rename from project-lakitu/app-containers/containerd/containerd-1.7.27-r2.ebuild rename to project-lakitu/app-containers/containerd/containerd-1.7.27-r3.ebuild
diff --git a/project-lakitu/app-containers/containerd/containerd-1.7.27.ebuild b/project-lakitu/app-containers/containerd/containerd-1.7.27.ebuild index 100cf48..c609144 100644 --- a/project-lakitu/app-containers/containerd/containerd-1.7.27.ebuild +++ b/project-lakitu/app-containers/containerd/containerd-1.7.27.ebuild
@@ -65,6 +65,7 @@ "${FILESDIR}"/1.4.0-customize-containerd-service.patch "${FILESDIR}"/1.7.27-CVE-2024-25621.patch "${FILESDIR}"/1.7.27-CVE-2025-64329.patch + "${FILESDIR}"/1.7.27-update-github.com-moby-spdystream-v0.5.1.patch ) src_prepare() {
diff --git a/project-lakitu/app-containers/containerd/files/1.7.27-update-github.com-moby-spdystream-v0.5.1.patch b/project-lakitu/app-containers/containerd/files/1.7.27-update-github.com-moby-spdystream-v0.5.1.patch new file mode 100644 index 0000000..dd69048 --- /dev/null +++ b/project-lakitu/app-containers/containerd/files/1.7.27-update-github.com-moby-spdystream-v0.5.1.patch
@@ -0,0 +1,756 @@ +From 8c26a76cbfa26764683df6ff23205ac68e310da3 Mon Sep 17 00:00:00 2001 +From: Kevin Berry <kpberry@google.com> +Date: Wed, 15 Apr 2026 00:14:02 +0000 +Subject: [PATCH] update github.com/moby/spdystream v0.5.1 + +Patch generated by setting spdystream version to 0.5.1 in go.mod and +running `go mod tidy && go mod vendor`. +--- + go.mod | 2 +- + go.sum | 4 +- + integration/client/go.sum | 1 + + vendor/github.com/moby/spdystream/NOTICE | 12 +++ + .../github.com/moby/spdystream/connection.go | 72 ++++++++++++----- + .../github.com/moby/spdystream/spdy/LICENSE | 27 +++++++ + .../github.com/moby/spdystream/spdy/PATENTS | 22 +++++ + .../moby/spdystream/spdy/dictionary.go | 16 ---- + .../moby/spdystream/spdy/options.go | 25 ++++++ + .../github.com/moby/spdystream/spdy/read.go | 58 ++++++++----- + .../github.com/moby/spdystream/spdy/types.go | 49 +++++++---- + .../github.com/moby/spdystream/spdy/write.go | 81 ++++++++++++------- + vendor/github.com/moby/spdystream/stream.go | 2 + + vendor/modules.txt | 2 +- + 14 files changed, 265 insertions(+), 108 deletions(-) + create mode 100644 vendor/github.com/moby/spdystream/spdy/LICENSE + create mode 100644 vendor/github.com/moby/spdystream/spdy/PATENTS + create mode 100644 vendor/github.com/moby/spdystream/spdy/options.go + +diff --git a/go.mod b/go.mod +index a7bb372ad..32090b08b 100644 +--- a/go.mod ++++ b/go.mod +@@ -114,7 +114,7 @@ require ( + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/pkcs11 v1.1.1 // indirect + github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect +- github.com/moby/spdystream v0.2.0 // indirect ++ github.com/moby/spdystream v0.5.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect +diff --git a/go.sum b/go.sum +index a80a1f3fc..324faae86 100644 +--- a/go.sum ++++ b/go.sum +@@ -512,8 +512,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh + github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= + github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= + github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +-github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +-github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= ++github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y= ++github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= + github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= + github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= + github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +diff --git a/integration/client/go.sum b/integration/client/go.sum +index e68d82b86..08ffb2ea6 100644 +--- a/integration/client/go.sum ++++ b/integration/client/go.sum +@@ -1835,6 +1835,7 @@ github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34 + github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= + github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= + github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= ++github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= + github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= + github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= + github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +diff --git a/vendor/github.com/moby/spdystream/NOTICE b/vendor/github.com/moby/spdystream/NOTICE +index b9b11c9ab..24e2e2aa3 100644 +--- a/vendor/github.com/moby/spdystream/NOTICE ++++ b/vendor/github.com/moby/spdystream/NOTICE +@@ -3,3 +3,15 @@ Copyright 2014-2021 Docker Inc. + + This product includes software developed at + Docker Inc. (https://www.docker.com/). ++ ++SPDY implementation (spdy/) ++ ++The spdy directory contains code derived from the Go project (golang.org/x/net). ++ ++Copyright 2009-2013 The Go Authors. ++Licensed under the BSD 3-Clause License. ++ ++Modifications Copyright 2014-2021 Docker Inc. ++ ++The BSD license text and Go patent grant are included in ++spdy/LICENSE and spdy/PATENTS. +diff --git a/vendor/github.com/moby/spdystream/connection.go b/vendor/github.com/moby/spdystream/connection.go +index d906bb05c..69ce4777e 100644 +--- a/vendor/github.com/moby/spdystream/connection.go ++++ b/vendor/github.com/moby/spdystream/connection.go +@@ -208,9 +208,10 @@ type Connection struct { + nextStreamId spdy.StreamId + receivedStreamId spdy.StreamId + +- pingIdLock sync.Mutex +- pingId uint32 +- pingChans map[uint32]chan error ++ // pingLock protects pingChans and pingId ++ pingLock sync.Mutex ++ pingId uint32 ++ pingChans map[uint32]chan error + + shutdownLock sync.Mutex + shutdownChan chan error +@@ -223,7 +224,13 @@ type Connection struct { + // NewConnection creates a new spdy connection from an existing + // network connection. + func NewConnection(conn net.Conn, server bool) (*Connection, error) { +- framer, framerErr := spdy.NewFramer(conn, conn) ++ return NewConnectionWithOptions(conn, server) ++} ++ ++// NewConnectionWithOptions creates a new spdy connection and applies frame ++// parsing limits via options. ++func NewConnectionWithOptions(conn net.Conn, server bool, opts ...spdy.FramerOption) (*Connection, error) { ++ framer, framerErr := spdy.NewFramerWithOptions(conn, conn, opts...) + if framerErr != nil { + return nil, framerErr + } +@@ -274,16 +281,20 @@ func NewConnection(conn net.Conn, server bool) (*Connection, error) { + // returns the response time + func (s *Connection) Ping() (time.Duration, error) { + pid := s.pingId +- s.pingIdLock.Lock() ++ s.pingLock.Lock() + if s.pingId > 0x7ffffffe { + s.pingId = s.pingId - 0x7ffffffe + } else { + s.pingId = s.pingId + 2 + } +- s.pingIdLock.Unlock() + pingChan := make(chan error) + s.pingChans[pid] = pingChan +- defer delete(s.pingChans, pid) ++ s.pingLock.Unlock() ++ defer func() { ++ s.pingLock.Lock() ++ delete(s.pingChans, pid) ++ s.pingLock.Unlock() ++ }() + + frame := &spdy.PingFrame{Id: pid} + startTime := time.Now() +@@ -345,6 +356,9 @@ Loop: + } else { + debugMessage("(%p) EOF received", s) + } ++ if spdyErr, ok := err.(*spdy.Error); ok && spdyErr.Err == spdy.InvalidControlFrame { ++ _ = s.conn.Close() ++ } + break + } + var priority uint8 +@@ -612,10 +626,14 @@ func (s *Connection) handleDataFrame(frame *spdy.DataFrame) error { + } + + func (s *Connection) handlePingFrame(frame *spdy.PingFrame) error { +- if s.pingId&0x01 != frame.Id&0x01 { ++ s.pingLock.Lock() ++ pingId := s.pingId ++ pingChan, pingOk := s.pingChans[frame.Id] ++ s.pingLock.Unlock() ++ ++ if pingId&0x01 != frame.Id&0x01 { + return s.framer.WriteFrame(frame) + } +- pingChan, pingOk := s.pingChans[frame.Id] + if pingOk { + close(pingChan) + } +@@ -703,7 +721,9 @@ func (s *Connection) shutdown(closeTimeout time.Duration) { + + var timeout <-chan time.Time + if closeTimeout > time.Duration(0) { +- timeout = time.After(closeTimeout) ++ timer := time.NewTimer(closeTimeout) ++ defer timer.Stop() ++ timeout = timer.C + } + streamsClosed := make(chan bool) + +@@ -730,17 +750,23 @@ func (s *Connection) shutdown(closeTimeout time.Duration) { + } + + if err != nil { +- duration := 10 * time.Minute +- time.AfterFunc(duration, func() { +- select { +- case err, ok := <-s.shutdownChan: +- if ok { +- debugMessage("Unhandled close error after %s: %s", duration, err) +- } +- default: +- } +- }) +- s.shutdownChan <- err ++ // default to 1 second ++ duration := time.Second ++ // if a closeTimeout was given, use that, clipped to 1s-10m ++ if closeTimeout > time.Second { ++ duration = closeTimeout ++ } ++ if duration > 10*time.Minute { ++ duration = 10 * time.Minute ++ } ++ timer := time.NewTimer(duration) ++ defer timer.Stop() ++ select { ++ case s.shutdownChan <- err: ++ // error was handled ++ case <-timer.C: ++ debugMessage("Unhandled close error after %s: %s", duration, err) ++ } + } + close(s.shutdownChan) + } +@@ -799,7 +825,9 @@ func (s *Connection) CloseWait() error { + func (s *Connection) Wait(waitTimeout time.Duration) error { + var timeout <-chan time.Time + if waitTimeout > time.Duration(0) { +- timeout = time.After(waitTimeout) ++ timer := time.NewTimer(waitTimeout) ++ defer timer.Stop() ++ timeout = timer.C + } + + select { +diff --git a/vendor/github.com/moby/spdystream/spdy/LICENSE b/vendor/github.com/moby/spdystream/spdy/LICENSE +new file mode 100644 +index 000000000..6a66aea5e +--- /dev/null ++++ b/vendor/github.com/moby/spdystream/spdy/LICENSE +@@ -0,0 +1,27 @@ ++Copyright (c) 2009 The Go Authors. All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are ++met: ++ ++ * Redistributions of source code must retain the above copyright ++notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above ++copyright notice, this list of conditions and the following disclaimer ++in the documentation and/or other materials provided with the ++distribution. ++ * Neither the name of Google Inc. nor the names of its ++contributors may be used to endorse or promote products derived from ++this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +diff --git a/vendor/github.com/moby/spdystream/spdy/PATENTS b/vendor/github.com/moby/spdystream/spdy/PATENTS +new file mode 100644 +index 000000000..733099041 +--- /dev/null ++++ b/vendor/github.com/moby/spdystream/spdy/PATENTS +@@ -0,0 +1,22 @@ ++Additional IP Rights Grant (Patents) ++ ++"This implementation" means the copyrightable works distributed by ++Google as part of the Go project. ++ ++Google hereby grants to You a perpetual, worldwide, non-exclusive, ++no-charge, royalty-free, irrevocable (except as stated in this section) ++patent license to make, have made, use, offer to sell, sell, import, ++transfer and otherwise run, modify and propagate the contents of this ++implementation of Go, where such license applies only to those patent ++claims, both currently owned or controlled by Google and acquired in ++the future, licensable by Google that are necessarily infringed by this ++implementation of Go. This grant does not include claims that would be ++infringed only as a consequence of further modification of this ++implementation. If you or your agent or exclusive licensee institute or ++order or agree to the institution of patent litigation against any ++entity (including a cross-claim or counterclaim in a lawsuit) alleging ++that this implementation of Go or any code incorporated within this ++implementation of Go constitutes direct or contributory patent ++infringement, or inducement of patent infringement, then any patent ++rights granted to you under this License for this implementation of Go ++shall terminate as of the date such litigation is filed. +diff --git a/vendor/github.com/moby/spdystream/spdy/dictionary.go b/vendor/github.com/moby/spdystream/spdy/dictionary.go +index 392232f17..5a5ff0e14 100644 +--- a/vendor/github.com/moby/spdystream/spdy/dictionary.go ++++ b/vendor/github.com/moby/spdystream/spdy/dictionary.go +@@ -1,19 +1,3 @@ +-/* +- Copyright 2014-2021 Docker Inc. +- +- Licensed under the Apache License, Version 2.0 (the "License"); +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +-*/ +- + // Copyright 2013 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. +diff --git a/vendor/github.com/moby/spdystream/spdy/options.go b/vendor/github.com/moby/spdystream/spdy/options.go +new file mode 100644 +index 000000000..ec03e0b9a +--- /dev/null ++++ b/vendor/github.com/moby/spdystream/spdy/options.go +@@ -0,0 +1,25 @@ ++package spdy ++ ++// FramerOption allows callers to customize frame parsing limits. ++type FramerOption func(*Framer) ++ ++// WithMaxControlFramePayloadSize sets the control-frame payload limit. ++func WithMaxControlFramePayloadSize(size uint32) FramerOption { ++ return func(f *Framer) { ++ f.maxFrameLength = size ++ } ++} ++ ++// WithMaxHeaderFieldSize sets the per-header name/value size limit. ++func WithMaxHeaderFieldSize(size uint32) FramerOption { ++ return func(f *Framer) { ++ f.maxHeaderFieldSize = size ++ } ++} ++ ++// WithMaxHeaderCount sets the maximum number of headers in a frame. ++func WithMaxHeaderCount(count uint32) FramerOption { ++ return func(f *Framer) { ++ f.maxHeaderCount = count ++ } ++} +diff --git a/vendor/github.com/moby/spdystream/spdy/read.go b/vendor/github.com/moby/spdystream/spdy/read.go +index 75ea045b8..2abb69433 100644 +--- a/vendor/github.com/moby/spdystream/spdy/read.go ++++ b/vendor/github.com/moby/spdystream/spdy/read.go +@@ -1,19 +1,3 @@ +-/* +- Copyright 2014-2021 Docker Inc. +- +- Licensed under the Apache License, Version 2.0 (the "License"); +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +-*/ +- + // Copyright 2011 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. +@@ -24,6 +8,7 @@ import ( + "compress/zlib" + "encoding/binary" + "io" ++ "io/ioutil" + "net/http" + "strings" + ) +@@ -59,6 +44,11 @@ func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error { + if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil { + return err + } ++ // Each setting is 8 bytes (4-byte id + 4-byte value). ++ // Payload is 4 bytes for numSettings + numSettings*8. ++ if h.length < 4 || numSettings > (h.length-4)/8 { ++ return &Error{InvalidControlFrame, 0} ++ } + frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings) + for i := uint32(0); i < numSettings; i++ { + if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil { +@@ -177,8 +167,19 @@ func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) ( + if err := binary.Read(f.r, binary.BigEndian, &length); err != nil { + return nil, err + } ++ maxControlFramePayload := uint32(MaxDataLength) ++ if f.maxFrameLength > 0 { ++ maxControlFramePayload = f.maxFrameLength ++ } ++ + flags := ControlFlags((length & 0xff000000) >> 24) + length &= 0xffffff ++ if length > maxControlFramePayload { ++ if _, err := io.CopyN(ioutil.Discard, f.r, int64(length)); err != nil { ++ return nil, err ++ } ++ return nil, &Error{InvalidControlFrame, 0} ++ } + header := ControlFrameHeader{version, frameType, flags, length} + cframe, err := newControlFrame(frameType) + if err != nil { +@@ -190,11 +191,22 @@ func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) ( + return cframe, nil + } + +-func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) { ++func (f *Framer) parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) { + var numHeaders uint32 + if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil { + return nil, err + } ++ maxHeaders := defaultMaxHeaderCount ++ if f.maxHeaderCount > 0 { ++ maxHeaders = f.maxHeaderCount ++ } ++ if numHeaders > maxHeaders { ++ return nil, &Error{InvalidControlFrame, streamId} ++ } ++ maxFieldSize := defaultMaxHeaderFieldSize ++ if f.maxHeaderFieldSize > 0 { ++ maxFieldSize = f.maxHeaderFieldSize ++ } + var e error + h := make(http.Header, int(numHeaders)) + for i := 0; i < int(numHeaders); i++ { +@@ -202,6 +214,9 @@ func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } ++ if length > maxFieldSize { ++ return nil, &Error{InvalidControlFrame, streamId} ++ } + nameBytes := make([]byte, length) + if _, err := io.ReadFull(r, nameBytes); err != nil { + return nil, err +@@ -217,6 +232,9 @@ func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } ++ if length > maxFieldSize { ++ return nil, &Error{InvalidControlFrame, streamId} ++ } + value := make([]byte, length) + if _, err := io.ReadFull(r, value); err != nil { + return nil, err +@@ -256,7 +274,7 @@ func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) + } + reader = f.headerDecompressor + } +- frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) ++ frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } +@@ -288,7 +306,7 @@ func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) e + } + reader = f.headerDecompressor + } +- frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) ++ frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } +@@ -320,7 +338,7 @@ func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) err + } + reader = f.headerDecompressor + } +- frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) ++ frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } +diff --git a/vendor/github.com/moby/spdystream/spdy/types.go b/vendor/github.com/moby/spdystream/spdy/types.go +index a254a43ab..a5528618c 100644 +--- a/vendor/github.com/moby/spdystream/spdy/types.go ++++ b/vendor/github.com/moby/spdystream/spdy/types.go +@@ -1,23 +1,9 @@ +-/* +- Copyright 2014-2021 Docker Inc. +- +- Licensed under the Apache License, Version 2.0 (the "License"); +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +-*/ +- + // Copyright 2011 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + ++// Modifications Copyright 2014-2021 Docker Inc. ++ + // Package spdy implements the SPDY protocol (currently SPDY/3), described in + // http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3. + package spdy +@@ -63,8 +49,20 @@ const ( + ) + + // MaxDataLength is the maximum number of bytes that can be stored in one frame. ++// ++// SPDY frame headers encode the payload length using a 24-bit field, ++// so the maximum representable size for both data and control frames ++// is 2^24-1 bytes. ++// ++// See the SPDY/3 specification, "Frame Format": ++// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1/ + const MaxDataLength = 1<<24 - 1 + ++const ( ++ defaultMaxHeaderFieldSize uint32 = 1 << 20 ++ defaultMaxHeaderCount uint32 = 1000 ++) ++ + // headerValueSepator separates multiple header values. + const headerValueSeparator = "\x00" + +@@ -269,6 +267,10 @@ type Framer struct { + r io.Reader + headerReader io.LimitedReader + headerDecompressor io.ReadCloser ++ ++ maxFrameLength uint32 // overrides the default frame payload length limit. ++ maxHeaderFieldSize uint32 // overrides the default per-header name/value length limit. ++ maxHeaderCount uint32 // overrides the default header count limit. + } + + // NewFramer allocates a new Framer for a given SPDY connection, represented by +@@ -276,6 +278,16 @@ type Framer struct { + // from/to the Reader and Writer, so the caller should pass in an appropriately + // buffered implementation to optimize performance. + func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { ++ return newFramer(w, r) ++} ++ ++// NewFramerWithOptions allocates a new Framer for a given SPDY connection and ++// applies frame parsing limits via options. ++func NewFramerWithOptions(w io.Writer, r io.Reader, opts ...FramerOption) (*Framer, error) { ++ return newFramer(w, r, opts...) ++} ++ ++func newFramer(w io.Writer, r io.Reader, opts ...FramerOption) (*Framer, error) { + compressBuf := new(bytes.Buffer) + compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary)) + if err != nil { +@@ -287,5 +299,10 @@ func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { + headerCompressor: compressor, + r: r, + } ++ for _, opt := range opts { ++ if opt != nil { ++ opt(framer) ++ } ++ } + return framer, nil + } +diff --git a/vendor/github.com/moby/spdystream/spdy/write.go b/vendor/github.com/moby/spdystream/spdy/write.go +index ab6d91f3b..75084d35d 100644 +--- a/vendor/github.com/moby/spdystream/spdy/write.go ++++ b/vendor/github.com/moby/spdystream/spdy/write.go +@@ -1,19 +1,3 @@ +-/* +- Copyright 2014-2021 Docker Inc. +- +- Licensed under the Apache License, Version 2.0 (the "License"); +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +-*/ +- + // Copyright 2011 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. +@@ -23,6 +7,7 @@ package spdy + import ( + "encoding/binary" + "io" ++ "math" + "net/http" + "strings" + ) +@@ -63,13 +48,21 @@ func (frame *RstStreamFrame) write(f *Framer) (err error) { + func (frame *SettingsFrame) write(f *Framer) (err error) { + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSettings +- frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4) ++ payloadLen := len(frame.FlagIdValues)*8 + 4 ++ if payloadLen > MaxDataLength { ++ return &Error{InvalidControlFrame, 0} ++ } ++ frame.CFHeader.length = uint32(payloadLen) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } +- if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil { ++ n := len(frame.FlagIdValues) ++ if uint64(n) > math.MaxUint32 { ++ return &Error{InvalidControlFrame, 0} ++ } ++ if err = binary.Write(f.w, binary.BigEndian, uint32(n)); err != nil { + return + } + for _, flagIdValue := range frame.FlagIdValues { +@@ -170,29 +163,41 @@ func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error { + + func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) { + n = 0 +- if err = binary.Write(w, binary.BigEndian, uint32(len(h))); err != nil { ++ numHeaders := len(h) ++ if numHeaders > math.MaxInt32 { ++ return n, &Error{InvalidControlFrame, 0} ++ } ++ if err = binary.Write(w, binary.BigEndian, uint32(numHeaders)); err != nil { + return + } +- n += 2 ++ n += 4 + for name, values := range h { +- if err = binary.Write(w, binary.BigEndian, uint32(len(name))); err != nil { ++ nameLen := len(name) ++ if nameLen > math.MaxInt32 { ++ return n, &Error{InvalidControlFrame, 0} ++ } ++ if err = binary.Write(w, binary.BigEndian, uint32(nameLen)); err != nil { + return + } +- n += 2 ++ n += 4 + name = strings.ToLower(name) + if _, err = io.WriteString(w, name); err != nil { + return + } +- n += len(name) ++ n += nameLen + v := strings.Join(values, headerValueSeparator) +- if err = binary.Write(w, binary.BigEndian, uint32(len(v))); err != nil { ++ vLen := len(v) ++ if vLen > math.MaxInt32 { ++ return n, &Error{InvalidControlFrame, 0} ++ } ++ if err = binary.Write(w, binary.BigEndian, uint32(vLen)); err != nil { + return + } +- n += 2 ++ n += 4 + if _, err = io.WriteString(w, v); err != nil { + return + } +- n += len(v) ++ n += vLen + } + return + } +@@ -216,7 +221,11 @@ func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) { + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSynStream +- frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10) ++ hLen := len(f.headerBuf.Bytes()) + 10 ++ if hLen > MaxDataLength { ++ return &Error{InvalidControlFrame, 0} ++ } ++ frame.CFHeader.length = uint32(hLen) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { +@@ -260,7 +269,11 @@ func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) { + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSynReply +- frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) ++ hLen := len(f.headerBuf.Bytes()) + 4 ++ if hLen > MaxDataLength { ++ return &Error{InvalidControlFrame, 0} ++ } ++ frame.CFHeader.length = uint32(hLen) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { +@@ -295,7 +308,11 @@ func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) { + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeHeaders +- frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) ++ hLen := len(f.headerBuf.Bytes()) + 4 ++ if hLen > MaxDataLength { ++ return &Error{InvalidControlFrame, 0} ++ } ++ frame.CFHeader.length = uint32(hLen) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { +@@ -323,7 +340,11 @@ func (f *Framer) writeDataFrame(frame *DataFrame) (err error) { + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } +- flagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data)) ++ dLen := len(frame.Data) ++ if dLen > MaxDataLength { ++ return &Error{InvalidDataFrame, frame.StreamId} ++ } ++ flagsAndLength := uint32(frame.Flags)<<24 | uint32(dLen) + if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil { + return + } +diff --git a/vendor/github.com/moby/spdystream/stream.go b/vendor/github.com/moby/spdystream/stream.go +index 404e3c02d..171c1e9e3 100644 +--- a/vendor/github.com/moby/spdystream/stream.go ++++ b/vendor/github.com/moby/spdystream/stream.go +@@ -305,6 +305,8 @@ func (s *Stream) Identifier() uint32 { + // IsFinished returns whether the stream has finished + // sending data + func (s *Stream) IsFinished() bool { ++ s.finishLock.Lock() ++ defer s.finishLock.Unlock() + return s.finished + } + +diff --git a/vendor/modules.txt b/vendor/modules.txt +index 533b56dda..ba46ac28d 100644 +--- a/vendor/modules.txt ++++ b/vendor/modules.txt +@@ -348,7 +348,7 @@ github.com/mistifyio/go-zfs/v3 + # github.com/moby/locker v1.0.1 + ## explicit; go 1.13 + github.com/moby/locker +-# github.com/moby/spdystream v0.2.0 ++# github.com/moby/spdystream v0.5.1 + ## explicit; go 1.13 + github.com/moby/spdystream + github.com/moby/spdystream/spdy +-- +2.54.0.rc0.605.g598a273b03-goog +