Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions SPECS/moby-engine/CVE-2026-39882.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From 7f1cb3338a73160ce9e13abc7c2ba1324e5e6dd6 Mon Sep 17 00:00:00 2001
From: AllSpark <allspark@microsoft.com>
Date: Wed, 15 Apr 2026 07:25:48 +0000
Subject: [PATCH] vendor(otel): limit response body size for OTLP HTTP exporter
(backport of #8108)

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: AI Backport of https://github.com/open-telemetry/opentelemetry-go/commit/5e363de517dba6db62736b2f5cdef0e0929b4cd0.patch
---
.../otlp/otlptrace/otlptracehttp/client.go | 21 +++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go
index 3a3cfec..33d0923 100644
--- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go
+++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go
@@ -18,6 +18,7 @@ import (
"bytes"
"compress/gzip"
"context"
+ "errors"
"fmt"
"io"
"net"
@@ -40,6 +41,13 @@ import (

const contentTypeProto = "application/x-protobuf"

+// maxResponseBodySize is the maximum number of bytes to read from a response
+// body. It is set to 4 MiB per the OTLP specification recommendation to
+// mitigate excessive memory usage caused by a misconfigured or malicious
+// server. If exceeded, the response is treated as a not-retryable error.
+// This is a variable to allow tests to override it.
+var maxResponseBodySize int64 = 4 * 1024 * 1024
+
var gzPool = sync.Pool{
New: func() interface{} {
w := gzip.NewWriter(io.Discard)
@@ -169,7 +177,11 @@ func (d *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
// Success, do not retry.
// Read the partial success message, if any.
var respData bytes.Buffer
- if _, err := io.Copy(&respData, resp.Body); err != nil {
+ if _, err := io.Copy(&respData, http.MaxBytesReader(nil, resp.Body, maxResponseBodySize)); err != nil {
+ var maxBytesErr *http.MaxBytesError
+ if errors.As(err, &maxBytesErr) {
+ return fmt.Errorf("response body too large: exceeded %d bytes", maxBytesErr.Limit)
+ }
return err
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be a partial fix. The upstream has two places where io.Copy is replaced with the updated signature, success and Error cases. Downstream also has the same but in switch case instead of handling it with if else. Following is the snippet,

         switch sc := resp.StatusCode; {
         case sc >= 200 && sc <= 299:
             // Success, do not retry.
             // Read the partial success message, if any.
             var respData bytes.Buffer
             if _, err := io.Copy(&respData, http.MaxBytesReader(nil, resp.Body, maxResponseBodySize)); err != nil 
...
         case sc == http.StatusTooManyRequests, sc == http.StatusServiceUnavailable:
             // Retry-able failures.  Drain the body to reuse the connection.
             if _, err := io.Copy(io.Discard, resp.Body); err != nil {
                 otel.Handle(err)
             }
             return newResponseError(resp.Header)

The io.Copy in error case also, we should put the same bound checking even though we are discarding it but read may still consume same high memory.

@@ -192,7 +204,12 @@ func (d *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc

case sc == http.StatusTooManyRequests, sc == http.StatusServiceUnavailable:
// Retry-able failures. Drain the body to reuse the connection.
- if _, err := io.Copy(io.Discard, resp.Body); err != nil {
+ var respData bytes.Buffer
+ if _, err := io.Copy(&respData, http.MaxBytesReader(nil, resp.Body, maxResponseBodySize)); err != nil {
+ var maxBytesErr *http.MaxBytesError
+ if errors.As(err, &maxBytesErr) {
+ return fmt.Errorf("response body too large: exceeded %d bytes", maxBytesErr.Limit)
+ }
otel.Handle(err)
}
return newResponseError(resp.Header)
--
2.43.0

8 changes: 6 additions & 2 deletions SPECS/moby-engine/moby-engine.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Summary: The open-source application container engine
Name: moby-engine
Version: 25.0.3
Release: 15%{?dist}
Release: 16%{?dist}
License: ASL 2.0
Group: Tools/Container
URL: https://mobyproject.org
Expand Down Expand Up @@ -31,6 +31,7 @@ Patch13: CVE-2024-51744.patch
Patch14: CVE-2025-58183.patch
#This can be removed when upgraded to v25.0.15
Patch15: fix-multiarch-image-push-tag.patch
Patch16: CVE-2026-39882.patch

%{?systemd_requires}

Expand Down Expand Up @@ -126,7 +127,10 @@ fi
%{_unitdir}/*

%changelog
* Wed Jan 21 2025 Kavya Sree Kaitepalli <kkaitepalli@microsoft.com> - 25.0.3-15
* Wed Apr 15 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 25.0.3-16
- Patch for CVE-2026-39882

* Tue Jan 21 2025 Kavya Sree Kaitepalli <kkaitepalli@microsoft.com> - 25.0.3-15
- Fix multiarch image push tag

* Sat Nov 15 2025 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 25.0.3-14
Expand Down
Loading