29.8.0
Release date |
Name |
Upstream release |
|---|---|---|
2026-OCT-05 |
MCR 29.8.0 |
Moby 29.8.0 and Docker CLI 29.8.0 |
Important
Due to the upgrade of containerd from 1.x to 2.x, before you upgrade from a previous MCR major release to MCR 29.8.0 you must upgrade
containerd.iobefore you upgradedocker-ee. In the event that you have upgraded both components at the same time and some of the containers that should have restarted remain stopped, you can get them running again by restarting MCR with the systemctl restart docker command.The bundled Compose plugin moves from the 5.1 line to 5.5, bringing the upstream 5.2 through 5.5 feature set. Compose 5.5 changes how it records image identity, so the first
docker compose upafter upgrade recreates containers once per project. On daemons that use the containerd image store (driver typeio.containerd.snapshotter.v1indocker infooutput), Compose recreates every container in every project. On overlay2 and other graphdrivers, Compose recreates only the containers of services that mount atype: imagevolume. Before you upgrade, check the image store of each daemon and exercise the upgrade in a staging environment. If a project cannot absorb the recreation, schedule the upgrade for a maintenance window. Compose 5.5 also honors thedaily,weekly, andevery_<n>pull_policyrefresh windows. Review any external workaround for the previous always-pull behavior, as it may now be redundant or conflict with the Compose file.
Highlights
Enhancement |
Detail |
|---|---|
FIPS packages built with the Go Cryptographic Module |
The FIPS installations no longer use or require the libcrypto3-mirantis package. It can safely be removed after upgrade. |
Changelog
MCR 29.8.0 comprises the Moby 29.8.0 and Docker CLI 29.8.0 upstream releases. In addition, changes are included for the interceding upstream 29.6.2, 29.7.0, 29.7.1 and 29.7.2 releases, for which there were no MCR releases.
Changes specific to MCR
The +fips packages are built with the Go Cryptographic Module (CryptoComply Native Go, CMVP #5349) instead of the Mirantis-patched Go toolchain, and libcrypto3-mirantis is no longer required.
Packages are published for Ubuntu 26.04 LTS (“Resolute”).
The Docker CLI now negotiates the ML-KEM hybrid (post-quantum) TLS key-exchange groups, matching the daemon. In 29.6.1.x the CLI’s build settings disabled them, so CLI-to-daemon TLS did not use post-quantum key exchange. This completes the PQC support introduced in 29.6.1.
Container policy enforcement moves to Open Policy Agent (OPA) 1.19, which replaces the WebAssembly runtime with wazero. Cory and Sopho still owe the user-facing OPA notes requested in the first comment.
Fixes backported ahead of upstream:
docker cp with nested bind mounts (moby/moby#53716; upstream will ship it in 29.8.2).
Swarm: published ports are reachable from bridge networks with icc=false, IPv4 only (from moby/moby#53723, not yet merged upstream).
Two security fixes; refer to Security below.
Changes from upstream
The upstream pull requests detailed in the sections that follow are those that pertain to the MCR product. For the complete list of changes and pull requests upstream, refer to the GitHub milestones.
New
--umaskflag fordocker create/docker run(HostConfig.Umask) sets the umask for a container’s main process, execs and health checks. (29.8.0)New
default-stop-timeoutdaemon option sets the stop timeout for containers that do not specify one. (29.7.0)The
imagemount type is no longer experimental. (29.7.0)The default container AppArmor profile template is now configurable, and AppArmor and SELinux rules prevent containers from creating
AF_VSOCKsockets through 32-bitsocketcall(2). (29.8.0)The
awslogslogging driver can attach service names, environments and custom CloudWatch entity attributes. (29.8.0)New
annotationfilter fordocker ps/GET /containers/json. (29.8.0)A set of Swarm networking reliability fixes: service-name resolution after missed membership announcements or transient node failures, and reduced, smoothed-out gossip traffic. (29.8.0)
The minimum supported Go version for the Go SDK is now 1.26. (29.8.0)
Note
With the containerd image store, the
daemon-wide max-concurrent-downloads and max-concurrent-uploads
limits are now honored (29.7.0). To keep the previous unlimited
behavior, set both to 0.
Security
MCR 29.8.0 release mitigates several CVEs that affect MCR container images. Click the dropdown link below for comprehensive details.
CVEs mitigated
CVE |
Image mitigated |
Problem details from upstream |
|---|---|---|
|
gRPC-Go is the Go language implementation of gRPC. Prior to 1.83.1, internal/transport/transport.go stores each fragmented HTTP/2 DATA frame as a separate recvMsg in recvBuffer, so millions of one-byte frames can consume disproportionate heap memory even when payload bytes remain within connection and stream flow-control windows. An unauthenticated remote attacker can use concurrent multiplexed streams to exhaust process memory and cause a runtime panic or out-of-memory termination. Receive-buffer compaction is enabled by default and can be controlled temporarily with GRPC_GO_EXPERIMENTAL_ENABLE_RECEIVE_BUFFER_COMPACTION. This issue is fixed in version 1.83.1. |
|
|
A malicious GOPROXY was previously capable of forging up to two sumdb tiles that allow for a requested module to bypass the GOSUMDB check and persist attacker-controlled module content to a local Go module cache. This attack allows for a malicious GOPROXY to serve malicious module content that cannot be detected by evaluating the transparency log. All tiles are now correctly verified against their parents. In order to determine if you have been affected: rm -r go.sum go.work. sum vendor/&& go mod tidy |
|
|
Handshake messages, such as KeyUpdate, are always considered as state-advancing, regardless of whether a handshake has been completed or not. As a result, a malicious client can keep sending KeyUpdate messages to force the server to keep performing key derivation operations indefinitely. |
|
|
Previously, resolving relative paths containing parent directory (‘..’) segments performed string conversions and buffer rewrites on each step, resulting in quadratic time complexity and high memory allocation overhead. Now, path resolution operates on a byte buffer using index-based backtracking for ‘..’ segments, eliminating the quadratic time complexity and significantly reducing memory allocations. |
|
|
Previously, DecodeElement would reset the depth counter causing it to never fire; this could lead to stack exhaustion. |
|
|
The source-address critical option in the Permissions returned by an authentication callback was only enforced for the PublicKeyCallback and VerifiedPublicKeyCallback paths, extending the fix for CVE-2026-46595. Permissions returned by the PasswordCallback, KeyboardInteractiveCallback, NoClientAuthCallback, and GSSAPIWithMICConfig.AllowLogin callbacks were not validated against the client’s remote address, so a source-address restriction set by those callbacks was silently ignored. The check is now applied to the Permissions returned by any authentication callback. |
|
|
When a server is configured to support unencrypted HTTP/2, it reads a few bytes from each new connection to see if they contain the HTTP/2 client preface. ReadHeaderTimeout is unexpectedly not being applied when doing this. |
|
|
A norm.Iter can enter an infinite loop when handling input containing invalid UTF-8 bytes. |
|
|
containerd is an open-source container runtime. In Versions prior to 2.3.2, 2.2.5 and 2.1.9, the CRI implementation improperly trusts Container Device Interface (CDI) annotations found within untrusted checkpoint image metadata during container restoration. When restoring a container from a checkpoint, containerd preserves CDI-related annotations from the checkpoint archive rather than relying solely on the pod’s create-time specification. This allows a user with pod creation permissions to bypass standard Kubernetes resource allocation and device plugin enforcement, injecting arbitrary CDI edits (such as device nodes and host mounts) into the restored container. Successful exploitation requires that the node has CDI enabled and contains a matching host CDI specification for the requested device; environments where CDI is disabled or lacking sensitive device specifications are not affected. This issue has been fixed in versions 2.3.2, 2.2.5 and 2.1.9. |
|
|
containerd is an open-source container runtime. In versions prior to 1.7.33, 2.3.2, 2.2.5, 2.1.9, and 2.0.10 the CRI plugin propagates labels from an image config (LABEL instruction in Dockerfile) to a container without validation. This may result in executing an arbitrary command on the host, via a plugin that consumes container labels for some operations. This issue has been fixed in versions 1.7.33, 2.3.2, 2.2.5, 2.1.9, and 2.0.10. |
|
|
containerd is an open-source container runtime. Versions prior to 2.3.2, 2.2.5 and 2.1.9 contain a vulnerability in the CRI checkpoint import process where it fails to validate the image references specified within a checkpoint image’s configuration. An attacker with permissions to create pods can use a crafted checkpoint image to force containerd to pull a malicious image and assign it an arbitrary local tag, thereby poisoning the node’s local image cache. Subsequently, if other pods on the same node attempt to use the poisoned tag with an IfNotPresent (or Never) pull policy, they will unknowingly execute the attacker’s malicious image instead of the legitimate one. This can lead to a compromise of the affected pods, allowing the attacker to execute arbitrary code under the victim pod’s identity. This issue has been fixed in versions 2.3.2, 2.2.5 and 2.1.9. |
|
|
oras-go is a Go library for managing OCI artifacts. Prior to 2.6.2, ensureLinkPath in content/file/utils.go:262-275 validates a hardlink target relative to the extract base but returns the unresolved target, causing os.Link(“victim.secret”, “<extract_base>/payload.tar.gz/evil_cwd_link”) to resolve header.Linkname against the process current working directory for a Typeflag=TypeLink entry such as Name=payload.tar.gz/evil_cwd_link and Linkname=”victim.secret” with io.deis.oras.content.unpack: “true”, which can expose or tamper with files such as .env, .git/config, .aws/credentials, and ~/.ssh/config. This issue is fixed in version 2.6.2. |
|
|
oras-go is a Go library for managing OCI artifacts. Prior to 2.6.1, registry/remote/repository.go in blobStore completePushAfterInitialPost follows a registry-controlled Location header during monolithic blob upload and reuses the Authorization header from the initial POST request for the subsequent PUT request, allowing a malicious registry to return a cross-host Location and receive the caller’s credentials at an attacker-controlled endpoint. This issue is fixed in version 2.6.1. |
|
|
sigstore-go is a Go library for Sigstore signing and verification. Prior to 1.2.0, a verifier configured with WithTransparencyLog(N>1) or WithSignedCertificateTimestamps(N>1) counts verified witnesses per entry or per validation path rather than per log authority, allowing a single compromised transparency log or CT log to satisfy multi-log threshold requirements and defeat the multi-log policy. This issue is fixed in version 1.2.0. |
|
|
oras-go is a Go library for managing OCI artifacts. Prior to 2.6.1, auth.Client follows the realm URL from a registry’s WWW-Authenticate: *** without validating the scheme or host, allowing a malicious or compromised registry to cause SSRF to internal networks such as http://169.254.169.254/, http://10.0.0.x/, and http://127.0.0.1/, or to downgrade a registry contacted over https:// to an http:// token endpoint in registry/remote/auth/client.go through Client.Do(), Client.fetchBearerToken(), fetchDistributionToken, and fetchOAuth2Token. This issue is fixed in version 2.6.1. |
|
|
containerd is an open-source container runtime. In versions prior to 1.7.32, 2.0.9, 2.2.4 and 2.3.1, containers launched with a numeric User directive that cannot be parsed as a 32-bit integer are incorrectly treated as a username, leading to runAsNonRoot evasion. If a crafted image provides an /etc/passwd file mapping this large numeric string to root, the container ultimately runs as root (UID 0). This allows the Kubernetes runAsNonRoot restriction to be bypassed, causing unexpected behavior for environments that require containers to run as a non-root user. This issue has been fixed in versions 1.7.32, 2.0.9, 2.2.4 and 2.3.1. |
|
|
Parsing an invalid SVCB or HTTPS RR can panic when the size of a parameter value overflows the message buffer. |
|
|
For certain crafted inputs, a ‘ed25519.PrivateKey’ was created by casting malformed wire bytes, leading to a panic when used. |
|
|
An incorrectly placed cast from bytes to int allowed for server-side panic in the AES-GCM packet decoder for well-crafted inputs. |
|
|
Previously, CVE-2024-45337 fixed an authorization bypass for misused ssh server configurations; if any other type of callback is passed other than public key, then the source-address validation would be skipped. |
|
|
Previously, a revoked ‘SignatureKey’ belonging to a CA was not correctly checked for revocation. Now, both the ‘key’ and ‘key.SignatureKey’ are checked for @revoked. |
|
|
Decoding a maliciously-crafted MIME header containing many invalid encoded-words can consume excessive CPU. |
|
|
Moby is an open source container framework. In Docker Engine prior to version 29.5.1, Docker Daemon versions 28.5.2 and prior, and Moby Daemon prior to version 2.0.0-beta.14, a race condition during docker cp mount setup allows a malicious container to redirect a bind mount target to an arbitrary host path, potentially overwriting host files or causing denial of service. This issue has been patched in Docker Engine version 29.5.1 and Moby Daemon version 2.0.0-beta.14. |
|
|
Moby is an open source container framework. In versions prior to 29.5.1 and in moby/moby v2 prior to v2.0.0-beta.14, when a compressed archive is uploaded to a container via PUT /containers/{id}/archive or piped through docker cp -, the daemon resolves decompression binaries (such as xz or unpigz) from the container’s filesystem rather than the host’s due to incorrect ordering of operations. A malicious container image containing a trojanized decompression binary can achieve arbitrary code execution with full daemon privileges, including host root UID and unrestricted capabilities, when a user uploads a compressed (xz or gzip) archive into that container. This issue is fixed in Docker Engine 29.5.1 and moby/moby v2.0.0-beta.14. Workarounds include only running containers from trusted images, using authorization plugins to restrict access to the PUT /containers/{id}/archive endpoint, and avoiding piping compressed archives into containers created from untrusted images |
|
|
OpenTelemetry-Go is the Go implementation of OpenTelemetry. From 1.15.0 to 1.42.0, the fix for CVE-2026-24051 changed the Darwin ioreg command to use an absolute path but left the BSD kenv command using a bare name, allowing the same PATH hijacking attack on BSD and Solaris platforms. This vulnerability is fixed in 1.43.0. |
|
|
SSH servers which use CertChecker as a public key callback without setting IsUserAuthority or IsHostAuthority could be caused to panic by a client presenting a certificate. CertChecker now returns an error instead of panicking when these callbacks are nil. |
|
|
When writing data larger than 4GB in a single Write call on an SSH channel, an integer overflow in the internal payload size calculation caused the write loop to spin indefinitely, sending empty packets without making progress. The size comparison now uses int64 to prevent truncation. |
|
|
A malicious SSH peer could send unsolicited global request responses to fill an internal buffer, blocking the connection’s read loop. The blocked goroutine could not be released by calling Close(), resulting in a resource leak per connection. Unsolicited global responses are now discarded. |
|
|
The RSA and DSA public key parsers did not enforce size limits on key parameters. A crafted public key with an excessively large modulus or DSA parameter could cause several minutes of CPU consumption during signature verification. This could be triggered by unauthenticated clients during public key authentication. RSA moduli are now limited to 8192 bits, and DSA parameters are validated per FIPS 186-2. |
|
|
When an SSH server authentication callback returned PartialSuccessError with non-nil Permissions, those permissions were silently discarded, potentially dropping certificate restrictions such as force-command after a second factor succeeded. Returning non-nil Permissions with PartialSuccessError now results in a connection error. |
|
|
On Unix systems, opening a file in an os.Root improperly follows symlinks to locations outside of the Root when the final path component of the a path is a symbolic link and the path ends in /. For example, ‘root.Open(“symlink/”)’ will open “symlink” even when “symlink” is a symbolic link pointing outside of the root. |
|
|
The ToASCII and ToUnicode functions incorrectly accept Punycode-encoded labels that decode to an ASCII-only label. For example, ToUnicode(“xn–example-.com”) incorrectly returns the name “example.com” rather than an error. This behavior can lead to privilege escalation in programs using the idna package. For example, a program which performs privilege checks on the ASCII hostname may reject “example.com” but permit “xn–example-.com”. If that program subsequently converts the ASCII hostname to Unicode, it will inadvertently permits access to the Unicode name “example.com”. |
|
|
Moby is an open source container framework. Prior to version 29.3.1, a security vulnerability has been detected that allows attackers to bypass authorization plugins (AuthZ). This issue has been patched in version 29.3.1. |
|
|
Moby is an open source container framework. Prior to version 29.3.1, a security vulnerability has been detected that allows plugins privilege validation to be bypassed during docker plugin install. Due to an error in the daemon’s privilege comparison logic, the daemon may incorrectly accept a privilege set that differs from the one approved by the user. Plugins that request exactly one privilege are also affected, because no comparison is performed at all. This issue has been patched in version 29.3.1. |
|
|
Enforce a recursion limit in Unmarshal to prevent stack exhaustion when parsing deeply-nested, recursive structures. |
|
|
When processing HTTP/2 SETTINGS frames, transport will enter an infinite loop of writing CONTINUATION frames if it receives a SETTINGS_MAX_FRAME_SIZE with a value of 0. |
|
|
gRPC-Go is the Go language implementation of gRPC. Versions prior to 1.79.3 have an authorization bypass resulting from improper input validation of the HTTP/2 :path pseudo-header. The gRPC-Go server was too lenient in its routing logic, accepting requests where the :path omitted the mandatory leading slash (e.g., Service/Method instead of /Service/Method). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official grpc/authz package) evaluated the raw, non-canonical path string. Consequently, “deny” rules defined using canonical paths (starting with /) failed to match the incoming request, allowing it to bypass the policy if a fallback “allow” rule was present. This affects gRPC-Go servers that use path-based authorization interceptors, such as the official RBAC implementation in google.golang.org/grpc/authz or custom interceptors relying on info.FullMethod or grpc.Method(ctx); AND that have a security policy contains specific “deny” rules for canonical paths but allows other requests by default (a fallback “allow” rule). The vulnerability is exploitable by an attacker who can send raw HTTP/2 frames with malformed :path headers directly to the gRPC server. The fix in version 1.79.3 ensures that any request with a :path that does not start with a leading slash is immediately rejected with a codes.Unimplemented error, preventing it from reaching authorization interceptors or handlers with a non-canonical path string. While upgrading is the most secure and recommended path, users can mitigate the vulnerability using one of the following methods: Use a validating interceptor (recommended mitigation); infrastructure-level normalization; and/or policy hardening. |
|
|
OpenTelemetry-Go is the Go implementation of OpenTelemetry. From 1.36.0 to 1.40.0, multi-value baggage: header extraction parses each header field-value independently and aggregates members across values. This allows an attacker to amplify cpu and allocations by sending many baggage: header lines, even when each individual value is within the 8192-byte per-value parse limit. This vulnerability is fixed in 1.41.0. |
|
|
(*x509.Certificate).VerifyHostname previously called matchHostnames in a loop over all DNS Subject Alternative Name (SAN) entries. This caused strings.Split(host, “.”) to execute repeatedly on the same input hostname. With a large DNS SAN list, verification costs scaled quadratically based on the number of SAN entries multiplied by the hostname’s label count. Because x509.Verify validates hostnames before building the certificate chain, this overhead occurred even for untrusted certificates. |
|
|
OpenTelemetry-Go is the Go implementation of OpenTelemetry. The OpenTelemetry Go SDK in version v1.20.0-1.39.0 is vulnerable to Path Hijacking (Untrusted Search Paths) on macOS/Darwin systems. The resource detection code in sdk/resource/host_id.go executes the ioreg system command using a search path. An attacker with the ability to locally modify the PATH environment variable can achieve Arbitrary Code Execution (ACE) within the context of the application. A fix was released with v1.40.0. |
|
|
The tar extraction routines in moby/go-archive (Unpack, UnpackLayer, Untar/UntarUncompressed, and the ApplyLayer helpers) do not confine filesystem operations to the destination directory. The extractor decides where each archive entry lands using lexical string checks and then performs the filesystem operation on a path that is resolved by the OS, so links introduced by the archive can be followed out of the destination directory. An attacker who controls the contents of an archive can create or overwrite files at arbitrary paths writable by the extracting process. |
GitHub milestones
The GitHub milestones offer full detail on the pull requests and changes as they correlate to the upstream Moby 29.8.0, 29.7.2, 29.7.1, 29.7.0, and 29.6.2 releases.
Major component versions
Note
MCR component versions are referenced from the latest builds in the
test-29.6.1.0 branch pool (Ubuntu 24.04 / noble, amd64).
Release-candidate (rc) and technology-preview (tp) suffixes have
been stripped.
Version detail for the major components that comprise MCR 29.6.1 is presented in the table below:
Component |
Upstream Version |
Mirantis Version |
|---|---|---|
29.8.0m1 |
||
29.8.0m1 |
||
2.3.4m2 |
||
1.4.3m1 |
||
– |
||
– |
||
0.35.1-m.1 |
||
Go runtime |
– |
|
0.33.0 (vendored in Moby 29.8.0) |
– |
|
3.0.2m2 |
||
gVisor |
– |
|
Docker Compose CLI plugin |
5.5.1 |
5.5.1m1 |
Platform test detail
Platform |
Kernel tested |
|---|---|
Oracle Linux 9.8 |
5.14.0-687.53.1.el9_8.x86_64 |
Oracle Linux 8.10 |
4.18.0-553.164.1.el8_10.x86_64 |
RHEL 10.2 |
6.12.0-211.61.1.el10_2.x86_64 |
RHEL 10.0 |
6.12.0-211.61.1.el10_2.x86_64 |
RHEL 9.8 |
5.14.0-687.45.1.el9_8.x86_64 |
RHEL 9.7 |
5.14.0-611.55.1.el9_7.x86_64 |
RHEL 9.6 |
5.14.0-570.141.1.el9_6.x86_64 |
RHEL 8.10 |
4.18.0-553.158.1.el8_10.x86_64 |
Rocky 10.1 |
6.12.0-211.61.1.el10_2.x86_64 |
Rocky 9.7 |
5.14.0-611.5.1.el9_7.x86_64 |
Rocky 8.10 |
4.18.0-553.137.1.el8_10.x86_64 |
SLES15 SP7 |
6.4.0-150700.53.81-default |
Ubuntu 26.04 |
7.0.0-1012-aws |
Ubuntu 24.04 |
7.0.0-1013-aws |
Ubuntu 22.04 |
6.8.0-1066-aws |
Windows 2025 Core |
10.0 26100 |
Windows 2022 Core |
10.0 20348 |