diff --git a/SPECS/containerized-data-importer/CVE-2026-35469.patch b/SPECS/containerized-data-importer/CVE-2026-35469.patch new file mode 100644 index 00000000000..73ddbd14629 --- /dev/null +++ b/SPECS/containerized-data-importer/CVE-2026-35469.patch @@ -0,0 +1,667 @@ +From 7bae9b9f46222c7eb0ffb2ea9dd48fc3577a77d3 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Wed, 6 May 2026 09:19:12 +0000 +Subject: [PATCH] vendor: spdystream: add framer options and guard against + oversized SPDY frames; limit header-size and header-count + +- Add NewConnectionWithOptions and NewFramerWithOptions with FramerOption to customize parsing limits +- Enforce max control frame payload, validate SETTINGS payload length +- Limit header count and header field sizes during parsing +- Close connection on InvalidControlFrame errors + +The "github.com/moby/spdystream" vendor package has been upgraded to version 0.5.1 with +this patch. But go.mod, go.sum and vendor/module.txt files have not been modified. + +Signed-off-by: Azure Linux Security Servicing Account +Upstream Patch Reference: https://github.com/moby/spdystream/releases/tag/v0.5.1 +--- + vendor/github.com/moby/spdystream/BUILD.bazel | 16 ---- + vendor/github.com/moby/spdystream/NOTICE | 12 +++ + .../github.com/moby/spdystream/connection.go | 29 ++++++- + .../moby/spdystream/spdy/BUILD.bazel | 14 ---- + .../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 ++++++++++++------- + 11 files changed, 233 insertions(+), 116 deletions(-) + delete mode 100644 vendor/github.com/moby/spdystream/BUILD.bazel + delete mode 100644 vendor/github.com/moby/spdystream/spdy/BUILD.bazel + 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/vendor/github.com/moby/spdystream/BUILD.bazel b/vendor/github.com/moby/spdystream/BUILD.bazel +deleted file mode 100644 +index e8458a5..0000000 +--- a/vendor/github.com/moby/spdystream/BUILD.bazel ++++ /dev/null +@@ -1,16 +0,0 @@ +-load("@io_bazel_rules_go//go:def.bzl", "go_library") +- +-go_library( +- name = "go_default_library", +- srcs = [ +- "connection.go", +- "handlers.go", +- "priority.go", +- "stream.go", +- "utils.go", +- ], +- importmap = "kubevirt.io/containerized-data-importer/vendor/github.com/moby/spdystream", +- importpath = "github.com/moby/spdystream", +- visibility = ["//visibility:public"], +- deps = ["//vendor/github.com/moby/spdystream/spdy:go_default_library"], +-) +diff --git a/vendor/github.com/moby/spdystream/NOTICE b/vendor/github.com/moby/spdystream/NOTICE +index b9b11c9..24e2e2a 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 d649ecc..69ce477 100644 +--- a/vendor/github.com/moby/spdystream/connection.go ++++ b/vendor/github.com/moby/spdystream/connection.go +@@ -224,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 + } +@@ -350,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 +@@ -712,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) + +@@ -739,7 +750,15 @@ func (s *Connection) shutdown(closeTimeout time.Duration) { + } + + if err != nil { +- duration := 10 * time.Minute ++ // 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 { +@@ -806,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/BUILD.bazel b/vendor/github.com/moby/spdystream/spdy/BUILD.bazel +deleted file mode 100644 +index 14ee701..0000000 +--- a/vendor/github.com/moby/spdystream/spdy/BUILD.bazel ++++ /dev/null +@@ -1,14 +0,0 @@ +-load("@io_bazel_rules_go//go:def.bzl", "go_library") +- +-go_library( +- name = "go_default_library", +- srcs = [ +- "dictionary.go", +- "read.go", +- "types.go", +- "write.go", +- ], +- importmap = "kubevirt.io/containerized-data-importer/vendor/github.com/moby/spdystream/spdy", +- importpath = "github.com/moby/spdystream/spdy", +- visibility = ["//visibility:public"], +-) +diff --git a/vendor/github.com/moby/spdystream/spdy/LICENSE b/vendor/github.com/moby/spdystream/spdy/LICENSE +new file mode 100644 +index 0000000..6a66aea +--- /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 0000000..7330990 +--- /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 392232f..5a5ff0e 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 0000000..ec03e0b +--- /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 75ea045..2abb694 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 a254a43..a552861 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 ab6d91f..75084d3 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 + } +-- +2.45.4 + diff --git a/SPECS/containerized-data-importer/containerized-data-importer.spec b/SPECS/containerized-data-importer/containerized-data-importer.spec index 863b57ca5d1..1b2836b0339 100644 --- a/SPECS/containerized-data-importer/containerized-data-importer.spec +++ b/SPECS/containerized-data-importer/containerized-data-importer.spec @@ -18,7 +18,7 @@ Summary: Container native virtualization Name: containerized-data-importer Version: 1.62.0 -Release: 3%{?dist} +Release: 4%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -32,6 +32,7 @@ Patch3: CVE-2025-58183.patch Patch4: CVE-2025-47911.patch Patch5: CVE-2025-58190.patch Patch6: CVE-2026-32288.patch +Patch7: CVE-2026-35469.patch BuildRequires: golang < 1.25 BuildRequires: golang-packaging BuildRequires: libnbd-devel @@ -226,6 +227,9 @@ install -m 0644 _out/manifests/release/cdi-cr.yaml %{buildroot}%{_datadir}/cdi/m %{_datadir}/cdi/manifests %changelog +* Wed May 06 2026 Azure Linux Security Servicing Account - 1.62.0-4 +- Patch for CVE-2026-35469 + * Mon Apr 20 2026 Azure Linux Security Servicing Account - 1.62.0-3 - Patch for CVE-2026-32288