Make sure the symlinks point to the same file; not if both are
identical (absolute or relative symlink); it's only for suppressing
the warning so not critical.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
While the "-modfile=vendor.mod" is slightly more correct, using a
symlink allows for most of the go tools to work "as usual", just
without an acual `go.mod` being committed in the repository.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Follow-up to 8f7dc04070, which updated the
minimum Go version in vendor.mod, but did not adjust this script.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- update minimum go version to 1.24
- use os.OpenFile with O_FILE_FLAG_SEQUENTIAL_SCAN on Go 1.26+
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This release include 3 security fixes following the security policy:
- mime: quadratic complexity in WordDecoder.DecodeHeader
Decoding a maliciously-crafted MIME header containing many invalid
encoded-words could consume excessive CPU.
The MIME decoder now better handles this case.
Thanks to p4p3r (https://hackerone.com/p4p3r_hak) for reporting this issue.
This is CVE-2026-42504 and Go issue https://go.dev/issue/79217.
- net/textproto: arbitrary input are included in errors without any escaping
When returning errors, functions in the net/textproto package would
include its input as part of the error, without any escaping. Note that
said input is often controlled by external parties when using this
package naturally. For example, a net/http client uses ReadMIMEHeader
when parsing the headers it receive from a server.
As a result, an attacker could inject arbitrary content into the error.
Practically, this can result in an attacker injecting misleading
content, terminal control bytes, etc. into a victim's output or logs.
This is CVE-2026-42507 and Go issue https://go.dev/issue/79346
- crypto/x509: split candidate hostname only once
(*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.
Thanks to Jakub Ciolek (https://ciolek.dev) for reporting this issue.
This is CVE-2026-27145 and https://go.dev/issue/79694.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.4
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This makes it easier to verify the sha matches the tag, and may help
with dependabot not updating the version-comment correctly.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Reduces the binary size (39810466 - 39289106 => 521360 (521 kb)
We only import google.golang.org/grpc as an indirect dependency, and
do not make gRPC connections.
grpcnotrace avoids importing golang.org/x/net/trace, which in turn enables
dead code elimination, which can yield 10-15% improvements in binary size
when tracing is not needed.
see https://github.com/grpc/grpc-go/blob/v1.81.1/trace_notrace.go#L23-L25
Before:
ls -l ./build/docker-darwin-arm64
-rwxr-xr-x 1 thajeztah staff 39810466 May 22 11:44 ./build/docker-darwin-arm64*
ls -lh ./build/docker-darwin-arm64
-rwxr-xr-x 1 thajeztah staff 38M May 22 11:44 ./build/docker-darwin-arm64*
After:
ls -l ./build/docker-darwin-arm64
-rwxr-xr-x 1 thajeztah staff 39289106 May 22 11:45 ./build/docker-darwin-arm64*
ls -lh ./build/docker-darwin-arm64
-rwxr-xr-x 1 thajeztah staff 37M May 22 11:45 ./build/docker-darwin-arm64*
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
security changes (not used in our code)
- html: escape greater-than symbol in doctype identifiers (CVE-2026-25681)
- html: improve Noah's Ark clause performance (CVE-2026-25680)
- html: properly render fostered elements in foreign content (CVE-2026-42502)
- html: properly check namespace in "in body" any other end tag (CVE-2026-42506)
- html: ignore duplicate attributes during tokenization (CVE-2026-27136)
other changes:
- quic: fix appendMaxDataFrame erroneously accumulating sentLimit
- quic: establish a "happened-before" relationship between stream write and read
- quic: fix buffer slicing when handling overlapping stream data
- http2: avoid API changes when built with go1.27
security announce: https://groups.google.com/g/golang-announce/c/iI-mYSI0lu8
full diff: https://github.com/golang/net/compare/v0.54.0...v0.55.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
update contributing guide link and improve PR template formatting in `.github/PULL_REQUEST_TEMPLATE.md`
Signed-off-by: Paulchen <lukas.23022005@gmail.com>
Signed-off-by: Lukas Michael <lukas.23022005@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The instructions in the file were outdated, and after removing them,
nothing really substantial was remaining, so let's just remove the
file for now.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a shorter name, which is more idiomatic, and prevents accidental
shadowing of types or arguments.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: https://github.com/golang/sys/compare/v0.43.0...v0.44.0
- unix: add CPUSetDynamic for systems with more than 1024 CPUs
- unix: avoid nil pointer dereference in Utime
- unix: automatically remove container created by mkall.sh
- cpu: use IsProcessorFeaturePresent to calculate ARM64 on windows
- windows: add GetIfTable2Ex, GetIpInterface{Entry,Table}, GetUnicastIpAddressTable
- windows: avoid uint16 overflow in NewNTUnicodeString
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- opts.ParseRestartPolicy: use a struct-literal and clarify that this
function only parses, but does not validate invalid combinations.
- cli/compose/convert: convertRestartPolicy: update doc to be more
clear on the order of preference and intent.
- cli/compose/convert: convertRestartPolicy: use a switch based on
known values to allow the exhaustive linter to catch missing options.
- cli/compose/convert: convertRestartPolicy: add validation for negative
values when converting the legacy service.restart policy.
- cli/compose/convert: convertRestartPolicy: always set MaxAttempts
and leave validation to the daemon.
opts: ParseRestartPolicy: improve validation of max restart-counts
Use the new container.ValidateRestartPolicy utility to verify if a max-restart-count
is allowed for the given restart-policy.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before:
docker run --rm --env-file=./no-such-file alpine
docker: open ./no-such-file: no such file or directory
Run 'docker run --help' for more information
After:
docker run --rm --env-file=./no-such-file alpine
docker: --env-file: open ./no-such-file: no such file or directory
Run 'docker run --help' for more information
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adds a "Response body size and partial buffering" subsection to
docs/extend/plugins_authorization.md documenting the 64 KiB
maxBufferSize constant in the daemon's internal responseModifier
(pkg/authorization/response.go in moby/moby) and the practical
implications for plugins that use ResponseBody inspection.
The existing docs (lines 81-87) say streaming endpoints such as
logs and events send only the HTTP request to plugins, but don't
explain the underlying mechanism. Plugin authors building
response-body redaction or content-filtering can be surprised when
the same effect happens on non-listed endpoints whose response is
produced through multiple writes exceeding the buffer or via an
io.WriteFlusher.
The 64 KiB buffer is observable from the public moby source, so
this PR is documentation catching up to existing behavior — not
a contract change.
Signed-off-by: Matteo Panzeri <matteo1782@gmail.com>
This release include 11 security fixes:
- cmd/go: malicious module proxy can bypass checksum database
A malicious module proxy could exploit a flaw in the go command's
validation of module checksums to bypass checksum database validation.
This vulnerability affects any user using an untrusted module proxy
(GOMODPROXY) or checksum database (GOSUMDB).
A malicious module proxy can serve altered versions of the Go toolchain.
When selecting a different version of the Go toolchain than the
currently installed toolchain (due to the GOTOOLCHAIN environment variable,
or a go.work or go.mod with a toolchain line), the go command will download
and execute a toolchain provided by the module proxy. A malicious module
proxy can bypass checksum database validation for this downloaded
toolchain.
Since this vulnerability affects the security of toolchain downloads,
setting GOTOOLCHAIN to a fixed version is not sufficient. You must upgrade
your base Go toolchain.
The go tool always validates the hash of a toolchain before executing it,
so fixed versions will refuse to execute any cached, altered versions of the
toolchain.
The go tool trusts go.sum files to contain accurate hashes of the current
module's dependencies. A malicious proxy exploiting this vulnerability to
serve an altered module will have caused an incorrect hash to be recorded
in the go.sum. Users who have configured a non-trusted GOPROXY can determine
if they have been affected by running "rm go.sum ; go mod tidy ; go mod verify",
which will revalidate all dependencies of the current module.
The specific flaw in more detail:
The go command consults the checksum database to validate downloaded modules,
when a module is not listed in the go.sum file. It verifies that the module hash
reported by the checksum database matches the hash of the downloaded module.
If, however, the checksum database returns a successful response that contains
no entry for the module, the go command incorrectly permitted validation to succeed.
A module proxy may mirror or proxy the checksum database, in which case the go
command will not connect to the checksum database directly. Checksums reported
by the checksum database are cryptographically signed, so a malicious proxy
cannot alter the reported checksum for a module. However, a proxy which returns
an empty checksum response, or a checksum response for an unrelated module,
could cause the go command to proceed as if a downloaded module has been validated.
The go command now properly checks checksum database responses to ensure
that the expected module signature is present, not just that if a signature is
present it matches the expectation.
Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-42501 and Go issue https://go.dev/issue/79070.
- net/http/httputil: ReverseProxy forwards queries with more than urlmaxqueryparams parameters
When used with a Rewrite function, or a Director function which parses query parameters,
ReverseProxy sanitizes the forwarded request to remove query parameters which are not
parsed by url.ParseQuery. ReverseProxy did not take ParseQuery's limit on the total number
of query parameters (controlled by GODEBUG=urlmaxqueryparams=N) into account.
This could permit ReverseProxy to forward a request containing a query parameter
that was not visible to the Rewrite function.
For example, the query "a1=x&a2=x&...&a10000=x&hidden=y" could forward the parameter
"hidden=y" while hiding it from the proxy's Rewrite function.
ReverseProxy now avoids forwarding parameters that exceed the ParseQuery limit.
This is CVE-2026-39825 and Go issue https://go.dev/issue/78948.
- net: panic in Dial and LookupPort when handling NUL byte on Windows
The Dial and LookupPort functions would panic on Windows when provided
with an input containing a NUL (0). These functions now return an error
rather than panicking.
This is CVE-2026-39836 and Go issue https://go.dev/issue/79006.
- net/mail: quadratic string concatenation in consumePhrase
Pathological inputs could cause DoS through consumePhrase
when parsing an email address according to RFC 5322.
This is CVE-2026-42499 and Go issue https://go.dev/issue/78987.
- net/mail: quadratic string concatentation in consumeComment
Well-crafted inputs reaching ParseAddress, ParseAddressList,
and ParseDate were able to trigger excessive CPU exhaustion
and memory allocations.
This is CVE-2026-39820 and Go issue https://go.dev/issue/78566.
- cmd/go: "go bug" follows symlinks in predictable temporary filenames
The "go bug" command wrote to two files with predictable names in
the system temporary directory (for example, "/tmp").
An attacker with access to the temporary directory could create a
symlink in one of these names, causing "go bug" to overwrite the
target of the symlink.
The "go bug" command now uses os.MkdirTemp to create a safe
working directory.
Thanks to Harshit Gupta (Mr HAX) for reporting this issue.
This is CVE-2026-39819 and Go issue https://go.dev/issue/78584.
- cmd/go: "go tool pack" does not sanitize output paths
The "go tool pack" subcommand is a minimal version of the Unix ar utility.
It is used by the compiler as an internal tool with known-good inputs.
The "pack" subcommand did not sanitize output filenames.
When invoked to extract a malicious archive file, it could write
files to arbitrary locations on the filesystem.
The "pack" subcommand now refuses to extract files with names
containing any directory components.
Thanks to Harshit Gupta (Mr HAX) for reporting this issue.
This is CVE-2026-39817 and Go issue https://go.dev/issue/78778.
- net/http: infinite loop in HTTP/2 transport when given bad SETTINGS_MAX_FRAME_SIZE
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.
This allows potential DoS against a client by a malicious server. HTTP/2
transport now properly checks that the received SETTINGS_MAX_FRAME_SIZE is
valid.
Thanks to Marwan Atia (marwansamir688@gmail.com) for reporting this issue.
This is CVE-2026-33814 and Go issue https://go.dev/issue/78476.
- html/template: escaper bypass leads to XSS
If a trusted template author were to write a
tag containing an empty type attribute or a type
attribute with an ASCII whitespace, the execution of
the template would incorrectly escape any data passed
into the block.
Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
This is CVE-2026-39826 and Go issue https://go.dev/issue/78981.
- net: crash when handling long CNAME response
When using LookupCNAME with the cgo DNS resolver,
a very long CNAME response could trigger a double-free of C memory
and a crash. The double-free has been fixed.
Thanks to hamayanhamayan for reporting this issue.
This is CVE-2026-33811 and Go issue https://go.dev/issue/78803.
- html/template: bypass of meta content URL escaping causes XSS
CVE-2026-27142 fixed a vulnerability in which URLs were not
correctly escaped inside of a tag's attribute.
If the URL content were to insert ASCII whitespaces around the
= rune inside of the attribute, the escaper would
fail to similarly escape it, leading to XSS.
Dynamic inputs to a tag's attribute are now
whitespace sanitized prior to escaping.
Thanks to Samy Ghannad for reporting this issue.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Previously, normalization was done before calling these functions,
which required implementations to normalize before using.
Move the normalization into the GetAuthConfig, GetCredentialsStore,
so that non-normalized hostnames will be able to resolve the correct
auth.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Several Labels() methods iterated over maps without sorting, producing
non-deterministic output.
In early versions of Go, map iteration order happened to be stable in
practice, so the original code appeared to work correctly.
Since Go 1.12, the runtime intentionally randomizes map iteration order,
making the output unpredictable between runs.
The API response produces sorted labels and the container formatter
already sorted its labels (changed in 5ee17eef).
Apply the same fix to the volume, network, config, and secret
formatters, and update tests to assert exact ordering instead of using
order-independent comparison.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Ensure PRs have a milestone set and that it matches the next release
version declared in the root VERSION file.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
go1.26.2 (released 2026-04-07) includes security fixes to the go command,
the compiler, and the archive/tar, crypto/tls, crypto/x509, html/template,
and os packages, as well as bug fixes to the go command, the go fix command,
the compiler, the linker, the runtime, and the net, net/http, and net/url
packages. See the Go 1.26.2 milestone on our issue tracker for details;
- https://github.com/golang/go/issues?q=milestone%3AGo1.26.2+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.26.1...go1.26.2
From the security announce:
We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy:
- os: Root.Chmod can follow symlinks out of the root on Linux
On Linux, if the target of Root.Chmod is replaced with a symlink while
the chmod operation is in progress, Chmod could operate on the target
of the symlink, even when the target lies outside the root.
The Linux fchmodat syscall silently ignores the AT_SYMLINK_NOFOLLOW flag,
which Root.Chmod uses to avoid symlink traversal. Root.Chmod checks its
target before acting and returns an error if the target is a symlink
lying outside the root, so the impact is limited to cases where the
target is replaced with a symlink between the check and operation.
On Linux, Root.Chmod now uses the fchmodat2 syscall when available, and
an workaround using /proc/self/fd otherwise.
Thanks to Uuganbayar Lkhamsuren for reporting this issue.
This is CVE-2026-32282 and Go issue https://go.dev/issue/78293.
- html/template: JS template literal context incorrectly tracked
Context was not properly tracked across template branches for JS template
literals, leading to possibly incorrect escaping of content when branches were
used.
Additionally template actions within JS template literals did not properly
track
the brace depth, leading to incorrect escaping being applied.
These issues could cause actions within JS template literals to be incorrectly
or improperly escaped, leading to XSS vulnerabilities.
This only affects templates that use template actions within JS template
literals.
This is CVE-2026-32289 and Go issue https://go.dev/issue/78331.
- crypto/x509: excluded DNS constraints not properly applied to wildcard domains
When verifying a certificate chain containing excluded DNS constraints, these
constraints are not correctly applied to wildcard DNS SANs which use a
different
case than the constraint.
For example, if a certificate contains the DNS name "*.example.com" and the
excluded DNS name "EXAMPLE.COM", the constraint will not be applied.
This only affects validation of otherwise trusted certificate chains, issued
by
a root CA in the VerifyOptions.Roots CertPool, or in the system certificate
pool.
This issue only affects Go 1.26.
Thank you to Riyas from Saintgits College of Engineering, k1rnt, @1seal for
reporting this issue.
This is CVE-2026-33810 and Go issue https://go.dev/issue/78332.
- cmd/compile: no-op interface conversion bypasses overlap checking
Previously, the compiler failed to unwrap pointers contained within
a no-op interface conversion leading to an incorrect determination
of a non-overlapping move.
To prevent unsafe move operations, the compiler will now unwrap all
such conversions before considering a move non-overlapping.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27144 and Go issue https://go.dev/issue/78371.
- cmd/compile: possible memory corruption after bound check elimination
Previously, slices and arrays accessed using induction variables
were sometimes incorrectly proved in-bound. If the induction variable
used for indexing were to overflow or underflow, it could allow access
to memory beyond the scope of the original slice or array.
To prevent this behavior, the compiler ensures that any mutated induction
variable that overflows/underflows with respect to its loop condition
is not used for bound check elimination.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27143 and Go issue https://go.dev/issue/78333.
- archive/tar: unbounded allocation when parsing old format GNU sparse map
tar.Reader could allocate an unbounded amount of memory when reading
a maliciously-crafted archive containing a large number of sparse
regions encoded in the "old GNU sparse map" format.
We now limit both the number of old GNU sparse map extension blocks,
and the total number of sparse file entries, regardless of encoding.
Thanks to Colin Walters (wal...@verbum.org) who initially reported this issue.
Thanks also to Uuganbayar Lkhamsuren (https://github.com/uug4na) and Jakub
Ciolek
who additionally reported this issue.
This is CVE-2026-32288 and Go issue https://go.dev/issue/78301.
- crypto/tls: multiple key update handshake messages can cause connection to
deadlock
If one side of the TLS connection sends multiple key update messages
post-handshake in a single record, the connection can deadlock, causing
uncontrolled consumption of resources. This can lead to a denial of service.
This only affects TLS 1.3.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32283 and Go issue https://go.dev/issue/78334.
- cmd/go: trust layer bypass when using cgo and SWIG
A well-crafted SWIG source file could take advantage
of a file-naming convention used inside the trust
boundary of the cgo compiler. Doing so could result
in arbitrary code execution during build time.
SWIG files are disallowed from using this convention.
Thank you to Juho Forsén of Mattermost for reporting this issue.
This is CVE-2026-27140 and Go issue https://go.dev/issue/78335.
- crypto/x509: unexpected work during chain building
During chain building, the amount of work that is done is not correctly
limited
when a large number of intermediate certificates are passed in
VerifyOptions.Intermediates, which can lead to a denial of service. This
affects
both direct users of crypto/x509 and users of crypto/tls.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32280 and Go issue https://go.dev/issue/78282.
- crypto/x509: inefficient policy validation
Validating certificate chains which use policies is unexpectedly inefficient
when certificates in the chain contain a very large number of policy mappings,
possibly causing denial of service.
This only affects validation of otherwise trusted certificate chains, issued
by
a root CA in the VerifyOptions.Roots CertPool, or in the system certificate
pool.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32281 and Go issue https://go.dev/issue/78281.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This code is using a `bytes.Buffer` to render the stats, before writing
the results to the CLI's output. Let's try to use bytes where possible
instead of converting to a string;
- Use the buffer's `Write` (and `Out().Write`) to write directly to the
buffer/writer where possible.
- Use `io.WriteString` instead of `fmt.Printf`
- Use `bytes.SplitSeq` instead of `strings.SplitSeq`
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Don't write lines back into the same buffer that's being read from when
clearing lines; add a separate output buffer to construct the output,
then write it to the CLI's output at once (to prevent terminal flicker).
Relates to / introduced in cb2f95ceee.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Update the GoDoc to better align with the actual implementation. The
"idOrName" is used for fuzzy-matching the container, which can result
in multiple stats for the same container:
docker ps --format 'table {{.ID}}\t{{.Names}}'
CONTAINER ID NAMES
b49e6c21d12e quizzical_maxwell
docker stats --no-stream quizzical_maxwell b49e6c21d12e b49e6
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
b49e6c21d12e quizzical_maxwell 0.10% 140.8MiB / 7.653GiB 1.80% 3.11MB / 13.4kB 115MB / 1.12MB 28
b49e6c21d12e quizzical_maxwell 0.10% 140.8MiB / 7.653GiB 1.80% 3.11MB / 13.4kB 115MB / 1.12MB 28
b49e6c21d12e quizzical_maxwell 0.10% 140.8MiB / 7.653GiB 1.80% 3.11MB / 13.4kB 115MB / 1.12MB 28
We should resolve the canonical ID once, then use that as reference
to prevent duplicates. Various parts in the code compare Container
against "ID" only (not considering "name" or "ID-prefix").
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `Context.preFormat` method normalizes the Format as given by the user,
and handles (e.g.) stripping the "table" prefix and replacing the "json"
format for the actual format (`{{json .}}`).
The method used a `finalFormat` field on the Context as intermediate,
and was required to be called before executing the format.
This patch adds a `Format.templateString()` method that returns the
parsed format instead of storing it on the Context. It is currently
not exported, but something we could consider in future.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
A tabwriter is backed by a buffer already, because it needs to re-flow columns
based on content written to it. This buffer was added in [moby@ea61dac9e6] as
part of a new feature to allow for custom delimiters; neither the patch, nor
code-review on the PR mention the extra buffer, so it likely was just overlooked.
This patch;
- removes the redundant buffer
- adds an early return for cases where no tabwriter is used.
[moby@ea61dac9e6]: https://github.com/moby/moby/commit/ea61dac9e6d04879445f9c34729055ac1bb15050
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Optimize formatting of container name(s);
- Inline `StripNamePrefix` in the loop, so that we don't have to
construct a new slice with names (in most cases only to pick
the first one).
- Don't use `strings.Split`, as it allocates a new slice and we only
used it to check if the container-name was a legacy-link (contained
slashes).
- Use a string-builder to concatenate names when not truncating instead
of using an intermediate slice (and `strings.Join`).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This function is very specific to attaching to containers, and probably
helps clarity to inline it where used.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When completing for commands that accept multiple arguments, we did
not remove suggestions that were already consumed. This could be
confusing if there was only 1 suggestion, in which case every `<tab>`
would automatically suggest the same name again:
docker rm -fv magical_lumiere magical_lumiere magical_lumiere
This patch adds a "Unique" helper to wrap a completion func to remove
completion results that are already consumed (i.e., appear in "args").
For example:
# initial completion: args is empty, so all results are shown
command <tab>
one two three
# "one" is already used so omitted
command one <tab>
two three
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- drop support for go1.24
- update vendor.mod to go1.25.0
- update //go:build tags to go1.25
The golang.org/x/ dependencies now require go1.25 as a minimum,
so updating our build tags accordingly.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This package imports all "importable" packages, i.e., packages that:
- are not applications ("main")
- are not internal
- and that have non-test go-files
We do this to verify that our code can be consumed as a dependency
in "module mode". When using a dependency that does not have a go.mod
(i.e.; is not a "module"), go implicitly generates a go.mod. Lacking
information from the dependency itself, it assumes "go1.16" language
(see [DefaultGoModVersion]). Starting with Go1.21, go downgrades the
language version used for such dependencies, which means that any
language feature used that is not supported by go1.16 results in a
compile error;
# github.com/docker/cli/cli/context/store
/go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
/go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
These errors do NOT occur when using GOPATH mode, nor do they occur
when using "pseudo module mode" (the "-mod=mod -modfile=vendor.mod"
approach used in this repository).
As a workaround for this situation, we must include "//go:build" comments
in any file that uses newer go-language features (such as the "any" type
or the "min()", "max()" builtins).
From the go toolchain docs (https://go.dev/doc/toolchain):
> The go line for each module sets the language version the compiler enforces
> when compiling packages in that module. The language version can be changed
> on a per-file basis by using a build constraint.
>
> For example, a module containing code that uses the Go 1.21 language version
> should have a go.mod file with a go line such as go 1.21 or go 1.21.3.
> If a specific source file should be compiled only when using a newer Go
> toolchain, adding //go:build go1.22 to that source file both ensures that
> only Go 1.22 and newer toolchains will compile the file and also changes
> the language version in that file to Go 1.22.
This file is a generated module that imports all packages provided in
the repository, which replicates an external consumer using our code
as a dependency in go-module mode, and verifies all files in those
packages have the correct "//go:build <go language version>" set.
To test this package:
make shell
make -C ./internal/gocompat/
make: Entering directory '/go/src/github.com/docker/cli/internal/gocompat'
GO111MODULE=off go generate .
GO111MODULE=on go mod tidy
GO111MODULE=on go test -v
# github.com/docker/cli/templates
../../templates/templates.go:13:17: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
# github.com/docker/cli/cli/compose/template
../../cli/compose/template/template.go:98:45: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/template/template.go:105:27: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/template/template.go:141:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
# github.com/docker/cli/cli/compose/types
../../cli/compose/types/types.go:53:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:86:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:105:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:137:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:211:20: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:343:35: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:442:40: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:469:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:490:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:587:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/types/types.go:442:40: too many errors
# github.com/docker/cli/cli/context/store
../../cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/context/store/store.go:75:23: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/context/store/metadatastore.go:43:58: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/context/store/metadatastore.go:48:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/context/store/metadatastore.go:80:30: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
# github.com/docker/cli/cli/command/idresolver
../../cli/command/idresolver/idresolver.go:6:2: "github.com/docker/docker/api/types" imported and not used
../../cli/command/idresolver/idresolver.go:7:2: "github.com/docker/docker/api/types/swarm" imported and not used
../../cli/command/idresolver/idresolver.go:9:2: "github.com/pkg/errors" imported and not used
../../cli/command/idresolver/idresolver.go:28:49: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/command/idresolver/idresolver.go:58:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
# github.com/docker/cli/cli/compose/schema
../../cli/compose/schema/schema.go:20:46: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/schema/schema.go:27:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/schema/schema.go:45:32: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
../../cli/compose/schema/schema.go:66:33: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
FAIL gocompat [build failed]
make: *** [Makefile:3: verify] Error 1
make: Leaving directory '/go/src/github.com/docker/cli/internal/gocompat'
[DefaultGoModVersion]: https://github.com/golang/go/blob/58c28ba286dd0e98fe4cca80f5d64bbcb824a685/src/cmd/go/internal/gover/version.go#L15-L24
[2]: https://go.dev/doc/toolchain
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Document how multiple --filter flags interact in prune commands:
different filter keys are ANDed (all conditions must match), while
multiple values for the same key are ORed (any value can match).
This addresses a gap in the documentation where users could not
determine whether multiple filters were combined with AND or OR
logic, which is especially important for prune commands where
the wrong assumption could lead to unintended data removal.
Closes#5899
Signed-off-by: Yoan Wainmann <yoan@mreshet.co.il>
When a plugin ignores context cancellation and the user sends 3 SIGINTs,
the CLI kills the plugin with SIGKILL. Previously the signal goroutine
called os.Exit(1) directly; a race existed where plugincmd.Run() could
return first (plugin was SIGKILL'd, so ws.ExitStatus() = -1) and the
main goroutine would call os.Exit(-1) = exit code 255 before the
goroutine reached os.Exit(1).
Fix by moving exit-code ownership to the main goroutine. The signal
goroutine closes forceExitCh before calling Kill(), guaranteeing the
channel is closed before plugincmd.Run() returns (the plugin can only
die after Kill() delivers SIGKILL; Run() only returns after the process
is reaped). The main goroutine checks forceExitCh after Run() returns
and performs the print + os.Exit(1) itself.
Also return from the signal goroutine after the force-kill to prevent
further loop iterations from calling close(forceExitCh) a second time
(which would panic), in case additional signals arrive while the kill
is in flight.
Fixes a flaky failure in TestPluginSocketCommunication/detached/
the_main_CLI_exits_after_3_signals where exit code 255 was observed
instead of 1 on loaded CI runners (RC Docker on Alpine).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Michael Zampani <michael.zampani@docker.com>
When linking containers through legacy links, a container can get multiple
names; its own name, and a name for each link it's providing:
# create two containers with links between them
docker run -d --name one nginx:alpine
docker run -d --name two --link one:link1 --link one:link2 --link one:link3 nginx:alpine
docker rm --link <tab>
two/link1 two/link2 two/link3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Inline StripNamePrefix and skip legacy links for completion.
Legacy links can be removed from a container, but only when
using `docker [container] rm --link <link-name>`.
When linking containers through legacy links, a container can get multiple
names; its own name, and a name for each link it's providing:
# create two containers with links between them
docker run -d --name one nginx:alpine
docker run -d --name two --link one:link1 --link one:link2 --link one:link3 nginx:alpine
# container "one" now has multiple names
docker ps --no-trunc --format '{{.Names}}'
two
one,two/link1,two/link2,two/link3
# running `docker rm --link` with a link-name removes a link:
docker rm --link two/link3
docker ps --no-trunc --format '{{.Names}}'
two
one,two/link1,two/link2
# but without `--link`, it resolves the linked container and removes it:
docker rm -fv two/link2
two/link2
docker ps --no-trunc --format '{{.Names}}'
two
Legacy links are deprecated, and this can be confusing, so let's not provide
completion for secondary names.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This code was assuming the API always returns container names with
a "/" prefix. While this is currently correct, we may at some point
stop doing so.
This patch changes the code to only trim "/" as prefix and not any
other character.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This code was assuming the API always returns container names with
a "/" prefix. While this is currently correct, we may at some point
stop doing so.
This patch changes the code to only trim "/" as prefix and not any
other character.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- skip aec to construct the formatting and use a const instead
- skip fmt.Println and write directly to the writer
- move newlines outside of the "bold" formatting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This allows for slighly cleaner / more natural placeholders, as it
doesn't require the context (`.`) to be specified;
- `{{command}}` instead of `{{.Command}}` or `{{command .}}`
- `{{flagValue "my-flag"}}` instead of `{{.FlagValue "my-flag"}} or `{{flagValue . "my-flag"}}`
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Define a local type for methods to expose to the template, instead of
passing the cobra.Cmd. This avoids templates depending on features
exposed by Cobra that are not part of the contract, and slightly
decouples the templat from the Cobra implementation.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- use `%q` instead of manually quoting the string
- use `%d` instead of manually converting the number to a string
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- add basic unit-test for the template utilities
- make sure the template parsing tests test both the current
template produced by the utilities, as well as a fixture
- rewrite the printer test to use fixtures
- use blackbox testing ("hooks_test")
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
These utilities are used by CLI-plugins; separate them from the render
code, which is used by teh CLI-plugin manager.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Rename the type to match the struct it's used for. Also;
- Fix the type of the NextSteps const
- Don't use iota for values; the ResponseType is used as
part of the "wire" format, which means that plugins using
the value can use a different version of the module code;
using iota increases the risk of (accidentally) changing
values, which would break the wire format.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Currently, the error was a plain "exit status 1"; make the error
message more informative if we need it :)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- update setHandler to accept multiple event-types
- pass a logger to the event-handlers with the common fields
already set.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Wire up the context explicitly instead of capturing it in the closures.
Also pass through the context to `watch` to replace the context.TODO()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When copying files with `docker cp`, the success message now shows both
the actual content size and the transferred (tar stream) size when they
differ, making it easier to understand compression and overhead:
Successfully copied 2.01MB (transferred 2.53MB) to ctr:/dir
Extract copySummary helper to keep copyToContainer under the gocyclo
complexity threshold. Add unit tests for copySummary and stdin path.
Signed-off-by: 4RH1T3CT0R7 <iprintercanon@gmail.com>
Add linux/riscv64 to the bin-image-cross platforms list so that
official release images include riscv64 binaries.
riscv64 is already present in the _platforms variable (line 38) and
used by the cross, dynbinary-cross, and plugins-cross targets. CI
already builds riscv64 binaries, but they are excluded from the
release image because bin-image-cross has its own platform list.
Closes#6857
Signed-off-by: Bruno Verachten <gounthar@gmail.com>
- commit e8dc2fce32 modernized loops to
range over int, which requires go1.22 or later.
- commit 85ebca52fd modernized code to
use stdlib min/max, which requires go1.21 or later.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
go1.25.8 (released 2026-03-05) includes security fixes to the html/template,
net/url, and os packages, as well as bug fixes to the go command, the compiler,
and the os package. See the Go 1.25.8 milestone on our issue tracker for details.
- 1.25.8 https://github.com/golang/go/issues?q=milestone%3AGo1.25.8+label%3ACherryPickApproved
- diff: https://github.com/golang/go/compare/go1.25.7...go1.25.8
- 1.26.1 https://github.com/golang/go/issues?q=milestone%3AGo1.26.1+label%3ACherryPickApproved
- diff: https://github.com/golang/go/compare/go1.26.0...go1.26.1
---
We have just released Go versions 1.26.1 and 1.25.8, minor point releases.
These releases include 5 security fixes following the security policy:
crypto/x509: incorrect enforcement of email constraints
- When verifying a certificate chain which contains a certificate containing
multiple email address constraints (composed of the full email address) which
share common local portions (the portion of the address before the '@'
character) but different domain portions (the portion of the address after the
'@' character), these constraints will not be properly applied, and only the
last constraint will be considered.
This can allow certificates in the chain containing email addresses which are
either not permitted or excluded by the relevant constraints to be returned by
calls to Certificate.Verify. Since the name constraint checks happen after chain
building is complete, this only applies to certificate chains which chain to
trusted roots (root certificates either in VerifyOptions.Roots or in the system
root certificate pool), requiring a trusted CA to issue certificates containing
either not permitted or excluded email addresses.
This issue only affects Go 1.26.
Thanks to Jakub Ciolek for reporting this issue.
This is CVE-2026-27137 and Go issue https://go.dev/issue/77952.
- crypto/x509: panic in name constraint checking for malformed certificates
Certificate verification can panic when a certificate in the chain has an empty
DNS name and another certificate in the chain has excluded name constraints.
This can crash programs that are either directly verifying X.509 certificate
chains, or those that use TLS.
Since the name constraint checks happen after chain building is complete, this
only applies to certificate chains which chain to trusted roots (root
certificates either in VerifyOptions.Roots or in the system root certificate
pool), requiring a trusted CA to issue certificates containing malformed DNS
names.
This issue only affects Go 1.26.
Thanks to Jakub Ciolek for reporting this issue.
This is CVE-2026-27138 and Go issue https://go.dev/issue/77953.
- html/template: URLs in meta content attribute actions are not escaped
Actions which insert URLs into the content attribute of HTML meta tags are not
escaped. This can allow XSS if the meta tag also has an http-equiv attribute
with the value "refresh".
A new GODEBUG setting has been added, htmlmetacontenturlescape, which can be
used to disable escaping URLs in actions in the meta content attribute which
follow "url=" by setting htmlmetacontenturlescape=0.
This is CVE-2026-27142 and Go issue https://go.dev/issue/77954.
- net/url: reject IPv6 literal not at start of host
The Go standard library function net/url.Parse insufficiently
validated the host/authority component and accepted some invalid URLs
by effectively treating garbage before an IP-literal as ignorable.
The function should have rejected this as invalid.
To prevent this behavior, net/url.Parse now rejects IPv6 literals
that do not appear at the start of the host subcomponent of a URL.
Thanks to Masaki Hara (https://github.com/qnighy) of Wantedly.
This is CVE-2026-25679 and Go issue https://go.dev/issue/77578.
- os: FileInfo can escape from a Root
On Unix platforms, when listing the contents of a directory using
File.ReadDir or File.Readdir the returned FileInfo could reference
a file outside of the Root in which the File was opened.
The contents of the FileInfo were populated using the lstat system
call, which takes the path to the file as a parameter. If a component
of the full path of the file described by the FileInfo is replaced with
a symbolic link, the target of the lstat can be directed to another
location on the filesystem.
The impact of this escape is limited to reading metadata provided by
lstat from arbitrary locations on the filesystem. This could be used
to probe for the presence or absence of files as well as gleaning
metadata like file sizes, but does not permit reading or writing files
outside the root.
The FileInfo is now populated using fstatat.
Thank you to Miloslav Trmač of Red Hat for reporting this issue.
This is CVE-2026-27139 and Go issue https://go.dev/issue/77827.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Add support for the `bind-create-src` option in bind mounts, which
instructs the daemon to create the source mountpoint on the host if it
doesn't exist.
This allows to replace the legacy `-v /src/dir:/dst` with the `--mount`.
Usage:
--mount type=bind,src=/host/path,dst=/container/path,bind-create-src
--mount type=bind,src=/host/path,dst=/container/path,bind-create-src=true
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Preserve all whitespace and treat the secret as an opaque value,
leaving it to the registry to (in)validate. We still check for
empty values in some places.
This partially reverts a21a5f4243,
but checks for empty (whitespace-only) passwords without mutating
the value.
This better aligns with [NIST SP 800-63B §5.1.1.2], which describes
that the value should be treated as opaque, preserving any other whitespace,
including newlines. Note that trimming whitespace may still happen elsewhere
(see [NIST SP 800-63B (revision 4) §3.1.1.2]);
> Verifiers **MAY** make limited allowances for mistyping (e.g., removing
> leading and trailing whitespace characters before verification, allowing
> the verification of passwords with differing cases for the leading character)
[NIST SP 800-63B §5.1.1.2]: https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver
[NIST SP 800-63B (revision 4) §3.1.1.2]: https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The code was using an intermediate map, indexed by name, for services
per file. Service-names should be unique per-file, so using an intermediate
map would not benefit us (we'd still have to loop over all of them to
produce the map, and again to iterate over the map)
Remove the intermediate map for overrides, and apply all overrides for
a service instead.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- construct merge-opts as a slice
- remove intermediate var for overrideServices
- use slices.SortFunc for sorting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The existing code only sorted by PublishedPort (host port), and did
not account for multiple ports mapped to the same host-port, but
using a different protocol.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
commit 880ef756b7 fixed static builds with
CGO, which included setting the `netgo` build-tag for static builds.
Starting with go1.19, the Go runtime on Windows now supports the `netgo` build-
flag to use a native Go DNS resolver. Prior to that version, the build-flag
only had an effect on non-Windows platforms. From the go1.19 release notes:
https://go.dev/doc/go1.19#net
> Resolver.PreferGo is now implemented on Windows and Plan 9. It previously
> only worked on Unix platforms. Combined with Dialer.Resolver and Resolver.Dial,
> it's now possible to write portable programs and be in control of all DNS name
> lookups when dialing.
>
> The net package now has initial support for the netgo build tag on Windows.
> When used, the package uses the Go DNS client (as used by Resolver.PreferGo)
> instead of asking Windows for DNS results. The upstream DNS server it discovers
> from Windows may not yet be correct with complex system network configurations,
> however.
This originally caused issues in the daemon, because the pure-go implementation
did not respect file-based resolution (`C:\Windows\System32\Drivers\etc\hosts`),
resulting in `localhost` not being resolvable, and custom entries in `.etc/hosts`
not being used.
That specific problem was resolved in go1.22 (through [golang/go@33d4a51]), but
other limitations may still apply, and resolver ordering may not respect VPN
adaptors (such as Twingate) and queries sent through the local network adapter
instead of the VPN tunnel, resulting in DNS resolution failures;
Get "https://example.com:2376/v1.52/containers/json": dial tcp: lookup example.com: i/o timeout
This patch unsets the `netgo` option when (cross-)compiling for Windows, similar
to the patch used for the daemon (see [moby/moby@53d1b12]).
[golang/go@33d4a51]: https://github.com/golang/go/commit/33d4a5105cf2b2d549922e909e9239a48b8cefcc
[moby/moby@53d1b12]: https://github.com/moby/moby/commit/53d1b12bc014b4243e9439fc2610eb4ef863659f
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
go1.25.7 (released 2026-02-04) includes security fixes to the go command
and the crypto/tls package, as well as bug fixes to the compiler and the
crypto/x509 package. See the Go 1.25.7 milestone on our issue tracker for
details:
https://github.com/golang/go/issues?q=milestone%3AGo1.25.7+label%3ACherryPickApproved
full diff: https://github.com/golang/go/compare/go1.25.6...go1.25.7
From the security mailing list:
> Hello gophers,
>
> We have just released Go versions 1.25.7 and 1.24.13, minor point releases.
>
> These releases include 2 security fixes following the security policy:
>
> - cmd/cgo: remove user-content from doc strings in cgo ASTs
>
> A discrepancy between how Go and C/C++ comments
> were parsed allowed for code smuggling into the
> resulting cgo binary.
>
> To prevent this behavior, the cgo compiler
> will no longer parse user-provided doc
> comments.
>
> Thank you to RyotaK (https://ryotak.net) of
> GMO Flatt Security Inc. for reporting this issue.
>
> This is CVE-2025-61732 and https://go.dev/issue/76697.
>
> - crypto/tls: unexpected session resumption when using Config.GetConfigForClient
>
> Config.GetConfigForClient is documented to use the original Config's session
> ticket keys unless explicitly overridden. This can cause unexpected behavior if
> the returned Config modifies authentication parameters, like ClientCAs: a
> connection initially established with the parent (or a sibling) Config can be
> resumed, bypassing the modified authentication requirements.
>
> If ClientAuth is VerifyClientCertIfGiven or RequireAndVerifyClientCert (on the
> server) or InsecureSkipVerify is false (on the client), crypto/tls now checks
> that the root of the previously-verified chain is still in ClientCAs/RootCAs
> when resuming a connection.
>
> Go 1.26 Release Candidate 2, Go 1.25.6, and Go 1.24.12 had fixed a similar issue
> related to session ticket keys being implicitly shared by Config.Clone. Since
> this fix is broader, the Config.Clone behavior change has been reverted.
>
> Note that VerifyPeerCertificate still behaves as documented: it does not apply
> to resumed connections. Applications that use Config.GetConfigForClient or
> Config.Clone and do not wish to blindly resume connections established with the
> original Config must use VerifyConnection instead (or SetSessionTicketKeys or
> SessionTicketsDisabled).
>
> Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
>
> This updates CVE-2025-68121 and Go issue https://go.dev/issue/77217.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This splits the validation code from parsing code, potentially allowing
us to either fully deferring it to the daemon, or to perform validation
separately.
For reference; daemon-side validation currently (docker 29.2.0) produces;
docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=writable alpine
docker: Error response from daemon: mount options conflict: !ReadOnly && BindOptions.ReadOnlyNonRecursive
docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=readonly alpine
docker: Error response from daemon: mount options conflict: !ReadOnly && BindOptions.ReadOnlyForceRecursive
Validation for BindOptions.Propagation is currently missing on the daemon;
docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=readonly,readonly alpine
# no error
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The daemon already validates the target, so we don't have to validate
if a target is set. Instead, we can ignore empty targets, but produce
an error if a target option was set, but set to an empty value.
With this patch applied, omitting a target option is ignored by the CLI,
but still invalidated by the daemon if the given mount-type requires a
mount target;
docker run --rm --mount type=bind,src=/var/run/docker.sock alpine
docker: Error response from daemon: invalid mount config for type "bind": field Target must not be empty
docker run --rm --mount type=bind,src=/var/run/docker.sock,dst=../foo alpine
docker: Error response from daemon: invalid mount config for type "bind": invalid mount path: '../foo' mount path must be absolute
When passing a target option (`target`, `dst`, or `destination`), the
CLI produces an error if the value is empty;
docker run --rm --mount type=bind,src=/var/run/docker.sock,dst= alpine
invalid argument "type=bind,src=/var/run/docker.sock,dst=" for "--mount" flag: invalid value for 'dst': mount target must be a non-empty value
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch:
docker run --rm --mount "" busybox
invalid argument "" for "--mount" flag: EOF
With this patch:
docker run --rm --mount "" busybox
invalid argument "" for "--mount" flag: value is empty
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Setting the source and target paths is not tied to the mount-type,
so these tests where covering the same code.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Add a custom join function that allows for non-string slices to be
joined, following the same rules as "fmt.Sprint", it will use the
fmt.Stringer interface if implemented, or "error" if the type has
an "Error()".
For maps, it joins the map-values, for example:
docker image inspect --format '{{join .Config.Labels ", "}}' ubuntu
24.04, ubuntu
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Prior to 1a502e91c9, failing to write the
container-ID to a file would return an error. After that change, we could
end up in a situation where the container was created successfully, but
we failed to inject the `config.json`. This failure would be returned as
an error, but the container was created (but no ID returned due to the error).
This patch changes the error to a warning; while not "ideal" (the container
is created, but in a "partial" state), we also shouldn't consider it to be
a hard failure; proceed as normal, to allow the user to either use the
container as-is, or to delete the container and try again.
Alternatively, we could join these errors, but the result will be ambiguous
in either case (container created, but an error occurred after the fact).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Ignore errors when trying to remove a CID-file that no longer exists;
also remove the path from the custom error as os.Remove already returns
a os.PathError, which includes the path.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Include the container-ID in the error message when failing to write
the ID to a file, so that the user can still find the ID of the container
that was created.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This releases includes 6 security fixes following the security policy:
- archive/zip: denial of service when parsing arbitrary ZIP archives
archive/zip used a super-linear file name indexing algorithm that is invoked the first time a file in an archive is opened. This can lead to a denial of service when consuming a maliciously constructed ZIP archive.
Thanks to Thanks to Jakub Ciolek for reporting this issue.
This is CVE-2025-61728 and Go issue https://go.dev/issue/77102.
- net/http: memory exhaustion in Request.ParseForm
When parsing a URL-encoded form net/http may allocate an unexpected amount of
memory when provided a large number of key-value pairs. This can result in a
denial of service due to memory exhaustion.
Thanks to jub0bs for reporting this issue.
This is CVE-2025-61726 and Go issue https://go.dev/issue/77101.
- crypto/tls: Config.Clone copies automatically generated session ticket keys, session resumption does not account for the expiration of full certificate chain
The Config.Clone methods allows cloning a Config which has already been passed
to a TLS function, allowing it to be mutated and reused.
If Config.SessionTicketKey has not been set, and Config.SetSessionTicketKeys has
not been called, crypto/tls will generate random session ticket keys and
automatically rotate them. Config.Clone would copy these automatically generated
keys into the returned Config, meaning that the two Configs would share session
ticket keys, allowing sessions created using one Config could be used to resume
sessions with the other Config. This can allow clients to resume sessions even
though the Config may be configured such that they should not be able to do so.
Config.Clone no longer copies the automatically generated session ticket keys.
Config.Clone still copies keys which are explicitly provided, either by setting
Config.SessionTicketKey or by calling Config.SetSessionTicketKeys.
This issue was discoverd by the Go Security team while investigating another
issue reported by Coia Prant (github.com/rbqvq).
Additionally, on the server side only the expiration of the leaf certificate, if
one was provided during the initial handshake, was checked when considering if a
session could be resumed. This allowed sessions to be resumed if an intermediate
or root certificate in the chain had expired.
Session resumption now takes into account of the full chain when determining if
the session can be resumed.
Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
This is CVE-2025-68121 and Go issue https://go.dev/issue/77113.
- cmd/go: bypass of flag sanitization can lead to arbitrary code execution
Usage of 'CgoPkgConfig' allowed execution of the pkg-config
binary with flags that are not explicitly safe-listed.
To prevent this behavior, compiler flags resulting from usage
of 'CgoPkgConfig' are sanitized prior to invoking pkg-config.
Thank you to RyotaK (https://ryotak.net) of GMO Flatt Security Inc.
for reporting this issue.
This is CVE-2025-61731 and go.dev/issue/77100.
- cmd/go: unexpected code execution when invoking toolchain
The Go toolchain supports multiple VCS which are used retrieving modules and
embedding build information into binaries.
On systems with Mercurial installed (hg) downloading modules (e.g. via go get or
go mod download) from non-standard sources (e.g. custom domains) can cause
unexpected code execution due to how external VCS commands are constructed.
On systems with Git installed, downloading and building modules with malicious
version strings could allow an attacker to write to arbitrary files on the
system the user has access to. This can only be triggered by explicitly
providing the malicious version strings to the toolchain, and does not affect
usage of @latest or bare module paths.
The toolchain now uses safer VCS options to prevent misinterpretation of
untrusted inputs. In addition, the toolchain now disallows module version
strings prefixed with a "-" or "/" character.
Thanks to splitline (@splitline) from DEVCORE Research Team for reporting this
issue.
This is CVE-2025-68119 and Go issue https://go.dev/issue/77099.
- crypto/tls: handshake messages may be processed at the incorrect encryption level
During the TLS 1.3 handshake if multiple messages are sent in records that span
encryption level boundaries (for instance the Client Hello and Encrypted
Extensions messages), the subsequent messages may be processed before the
encryption level changes. This can cause some minor information disclosure if a
network-local attacker can inject messages during the handshake.
Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
This is CVE-2025-61730 and Go issue https://go.dev/issue/76443
View the release notes for more information:
https://go.dev/doc/devel/release#go1.25.6
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Before this patch, lintian would complain about some lines being too long:
lintian ./*.deb
...
W: docker-ce-cli: groff-message troff:<standard input>:642: warning [p 8, 10.2i, div '3tbd1,1', 0.0i]: cannot break line [usr/share/man/man1/docker-run.1.gz:1]
groff -t -man ./docker-run.1 > /dev/null
troff:./docker-run.1:602: warning [p 9, 2.8i]: cannot adjust line
troff:./docker-run.1:669: warning [p 10, 2.5i, div '3tbd1,1', 0.0i]: cannot break line
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- remove constructor
- fix mixed pointer/non-pointer receivers
- just embed the error we want to produce
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this change, the detach-keys were not validated, and the code either
fell back to the default sequence, or returned an obscure error if the
invalid sequence would produce an error on the daemon;
Before this patch:
docker run -it --rm --detach-keys=shift-a,b busybox
unable to upgrade to tcp, received 400
With this patch:
docker run -it --rm --detach-keys=shift-a,b busybox
invalid detach keys (shift-a,b): Unknown character: 'shift-a'
Note that the "unable to upgrade to tcp, received 400" error is still
something to be looked into; the client currently discards error messages
coming from the daemon.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a more generic "clientOptions" field to store options to apply
when constructing the API client, instead of a dedicated field for
user-agent.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Changed the environment variables section description from:
"The following list of environment variables are supported by the `docker` command line:"
To:
"The following environment variables control the behavior of the `docker` command-line client:"
This makes it clearer that these variables control Docker's behavior, and uses the more precise term "command-line client" instead of "command line".
Signed-off-by: Andrew Hopp <andrew.hopp@me.com>
`go list` expects a module to be valid, which means that dependencies must
either be vendored, or downloaded in the module cache. However, when working
in GOPATH mode, `go.mod` files are ignored, which means that `go list` will
traverse subdirectories, even if those are a separate module, and those modules
may not have their dependencies present.
In our case, we try to exclude those modules from paths to be tested, but
do so based on the _result_ of `go list`, which already produces errors before
we filter.
These errors do not impact out tests, as we don't run tests for those paths,
but do produce noise in CI, which can be confusing;
go test -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '/vendor/|/e2e/|/cmd/docker-trust')
cmd/docker-trust/internal/trust/trust.go:28:2: cannot find package "github.com/theupdateframework/notary" in any of:
/go/src/github.com/docker/cli/vendor/github.com/theupdateframework/notary (vendor tree)
/usr/local/go/src/github.com/theupdateframework/notary (from $GOROOT)
/go/src/github.com/theupdateframework/notary (from $GOPATH)
cmd/docker-trust/internal/trust/trust.go:29:2: cannot find package "github.com/theupdateframework/notary/client" in any of:
/go/src/github.com/docker/cli/vendor/github.com/theupdateframework/notary/client (vendor tree)
/usr/local/go/src/github.com/theupdateframework/notary/client (from $GOROOT)
/go/src/github.com/theupdateframework/notary/client (from $GOPATH)
This patch adds a symlink for `go.mod` and `go.sum`, so that listing the
packages happens in go modules mode, and doesn't traverse to other modules,
such as `cmd/docker-trust`.
- updates 06914dd0ff, which attempted to
exclude the docker-trust plugin
- similar to cee9ea67fc, which made this
change for the linter.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- trace: fix data race in RenderEvents
- http2, webdav, websocket: fix %q verb uses with wrong type
- http2: don't PING a responsive server when resetting a stream
- http2: support net/http.Transport.NewClientConn
full diff: https://github.com/golang/net/compare/v0.47.0...v0.48.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This was introduced in 9c10a9c9ac, which added
use of the network.ParsePortRange.All method, which uses an iterator and
requires go1.23;
opts/swarmopts/port.go:172:18: cannot range over pr.All() (value of func type iter.Seq[network.Port]): requires go1.23 or later (-lang was set to go1.16; check go.mod)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
commit 4d3a76d71e updated the list of directories
for discovering CLI plugins, adding `%ProgramFiles%\Docker\cli-plugins` for
system-wide plugins.
For backward compatibility, the `%PROGRAMDATA%\Docker\cli-plugins` was kept,
however, this location is no longer used, and not generally recommended for
storing non-data content (such as CLI plugin binaries). From the [ProgramData]
documentation:
> ProgramData specifies the path to the program-data folder (normally C:\ProgramData).
> Unlike the Program Files folder, this folder can be used by applications to store
> data for standard users, because it does not require elevated permissions.
It also mentions "It can’t contain any serviceable components.", effectively
meaning that these paths should not contain data that is managed (through
updates etc.), making it a poor choice for installing "system wide" CLI plugins.
This patch removes the path from the list, given that this location is no longer
used by Docker Desktop, and the CLI-plugin API is considered an internal
implementation (since 459c6082f8).
[ProgramData]: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-folderlocations-programdata
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
about:"General Docker Desktop issues (installation, upgrades, UI, networking on macOS/Windows, WSL2, etc.) should be filed in the Docker Desktop feedback tracker (not docker/cli)."
- G306# G306: Expect WriteFile permissions to be 0600 or less (too restrictive; also flags "0o644" permissions)
- G307# G307: Deferring unsafe method "*os.File" on type "Close" (also EXC0008); (TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close")
os-chdir:false# FIXME(thaJeztah): Disable `os.Chdir()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-background:false# FIXME(thaJeztah): Disable `context.Background()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-todo:false# FIXME(thaJeztah): Disable `context.TODO()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
exclusions:
# We prefer to use an "linters.exclusions.rules" so that new "default" exclusions are not
# automatically inherited. We can decide whether or not to follow upstream
@@ -225,13 +227,10 @@ linters:
linters:
- staticcheck
# Ignore deprecation linting for cli/command/stack/*.
#
# FIXME(thaJeztah): remove exception once these functions are un-exported or internal; see https://github.com/docker/cli/pull/6389
- text:'^(SA1019):'
path:"cli/command/stack"
# TODO(thaJeztah): remove once https://github.com/leighmcculloch/gocheckcompilerdirectives/issues/7 is fixed.
pCmd:=exec.CommandContext(ctx,p.Path,p.Name,metadata.HookSubcommandName,string(hDataBytes))// #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments"
flags.BoolVarP(&opts.followLink,"follow-link","L",false,"Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.followLink,"follow-link","L",false,"Always follow symlinks in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID,"archive","a",false,"Archive mode (copy all uid/gid information)")
flags.BoolVarP(&opts.quiet,"quiet","q",false,"Suppress progress output during copy. Progress output is automatically suppressed if no terminal is attached")
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.