Go 1.20.5 repairs trust boundaries in cgo builds and privileged binaries
June's Go security release addresses code injection through cgo build inputs and unsafe runtime behavior in setuid and setgid programs. The relevant privileges belong to the build process as well as the deployed executable.
A dependency can affect a machine before the resulting application ever runs. Go's June security release includes fixes for code injection while the Go command processes cgo inputs. The same release addresses a different privilege boundary in Unix setuid and setgid executables. These failures concern the authority of the process interpreting an input, whether that process is a build command or a deployed program.
The Go 1.20.5 release record dates the release to June 6 and lists four security fixes in cmd/go and the runtime. The release announcement groups them into three descriptions, with two CVEs assigned to linker-flag sanitization. It also announces Go 1.19.10 with corresponding security corrections.
I value Go's integrated build tooling because it keeps many ordinary build decisions understandable. That integration also makes the command's handling of external tool inputs part of the language ecosystem's security obligations. A familiar go command can still cross into a C toolchain with its own input rules.
A directory name could alter generated code
CVE-2023-29402 concerns unexpected code generation during cgo builds. The announcement identifies untrusted modules containing directories whose names include newline characters. The Go command could generate unexpected code from those inputs, which could change the behavior of the resulting program.
A path is data to the build command. Once incorporated into another representation, its characters may also have syntactic meaning. A newline is especially significant when generated content has line-oriented structure. The disclosed defect shows that accepting a path and safely representing that path in generated code are separate responsibilities.
The announcement makes an important qualification about acquisition. Modules retrieved through the Go command's module-aware mechanism are not affected by this issue. It explicitly distinguishes GOPATH-mode retrieval, which may be affected. That qualification should remain attached to the vulnerability when assessing a build environment.
It would be inaccurate to collapse the problem into a claim that every ordinary module download can trigger this particular newline-directory defect. The disclosed conditions concern how an untrusted module reaches the build and the directory names it contains. A checkout or other source input can present a different set of paths from the module retrieval mechanism the announcement excludes.
The correction protects the code generation boundary. The application's own source can be reasonable while the build command mishandles metadata surrounding that source. That is why reviewing only the final Go files does not describe the entire input interpreted during a cgo build.
Linker flags could execute code during the build
CVE-2023-29404 and CVE-2023-29405 concern improper sanitization of linker flags supplied through #cgo LDFLAGS directives. The announcement says the Go command may execute arbitrary code at build time when using cgo. Commands that build untrusted code are relevant to the stated exposure.
This is a different consequence from merely producing a binary that behaves unexpectedly later. Build-time execution uses the environment and authority of the build process. The resulting application does not need to be installed or launched for that phase to matter. A build machine's credentials and writable locations consequently belong in the analysis of who can influence its inputs.
The directive is significant because it is part of a package's source, yet asks the Go command to pass instructions into another tool. Sanitization must preserve the supported linking operation without allowing a package to use that channel for unintended execution. That is a narrower and more demanding contract than treating all directive contents as trusted shell text.
The two CVE identifiers should not obscure their shared operational condition. Both descriptions concern cgo and linker flags. A statement that an application never accepts untrusted HTTP requests says nothing about whether its build consumed an untrusted package with these directives. Runtime input validation and build input handling address different stages.
My preference is to assess build commands with the same attention to authority that a service receives. A dependency is an input to software running on the builder. The relevant question is what that input can make the builder do before it produces an artifact.
Privileged executables needed different runtime behavior
CVE-2023-29403 concerns Unix programs with setuid or setgid bits. The public issue description explains that the Go runtime did not behave differently for these privileged executables. Two consequences appear in the disclosure, both involving process behavior outside an application's ordinary request logic.
First, executing such a program with standard input or output descriptors closed could make subsequent file opens occupy those descriptor positions. The announcement describes unexpected content being read or written with elevated privileges. The danger depends on the relationship between descriptor state and later runtime or application activity.
A closed standard descriptor is an environmental condition supplied at process launch. Code that assumes those descriptors already refer to the usual streams may operate on a different file after later opens. With elevated privileges, that mismatch can have consequences beyond an ordinary user's own files. The disclosed issue is therefore about privileged process initialization as well as file operations.
Second, the announcement says termination through a panic or signal could disclose register contents. Diagnostic behavior that is useful for an ordinary process can require different treatment when the process has elevated privileges. Information about privileged execution is itself an output whose audience matters.
The patch's scope should remain precise. These are documented consequences for setuid and setgid binaries on Unix platforms. They do not establish that every Go executable runs with elevated privileges. Applications that do use those mechanisms depend on the runtime understanding the different security context.
The security correction also changes an integration boundary
The announcement thread contains a same-day follow-up from Ian Lance Taylor about a regression in the linker-flag change. Go 1.20.5 and Go 1.19.10 break some uses of #cgo LDFLAGS when invoked with -compiler=gccgo, including some GoLLVM cases. He distinguishes those cases from people using the Go command distributed with those toolchains, which is unaffected.
That qualification matters for interpreting the release as it exists today. The security fix is available, and a specific alternate-compiler integration has a reported problem. The follow-up says a correction is planned for the next minor release. It provides no basis for claiming that a later correction has already shipped.
For an ordinary Go build using cgo, the release repairs the stated code-generation and linker-input failures. For a privileged Unix executable, rebuilding with the corrected runtime adopts a different part of the release. Both paths depend on selecting the patched toolchain for the work that produces the executable, because the corrected behavior belongs to the builder and runtime implementation.