Skip to content

chore: bump toolkit to go 1.25 to fix CVEs - #18645

Open
Muhammad Falak R Wani (mfrw) wants to merge 12 commits into
3.0-devfrom
mfrw/toolkit-update-go-1.25
Open

chore: bump toolkit to go 1.25 to fix CVEs#18645
Muhammad Falak R Wani (mfrw) wants to merge 12 commits into
3.0-devfrom
mfrw/toolkit-update-go-1.25

Conversation

@mfrw

Copy link
Copy Markdown
Member
  • chore: bump toolkit to go 1.25 to fix CVEs
  • chore: install upstream go 1.25 on Ubuntu releases without a distro package
  • fix: prefer the distro golang package on Ubuntu releases that have it
  • fix: do not overwrite an existing Go toolchain in /usr/local/go
  • fix: warn when another go on PATH shadows the installed toolchain
  • docs: drop the stale msft-golang note from the Azure Linux prerequisites
  • docs: record how and when to advance the pinned Go version
  • fix: explain a checksum mismatch instead of printing sha256sum's FAILED

Co-authored-by: Daniel McIlvaney <damcilva@microsoft.com>
…ackage

Ubuntu 26.04 packages Go 1.25 as golang-1.25-go, but 22.04 and 24.04 do not
package it at all, so installing prerequisites there leaves the toolkit without
a usable Go. The apt package also is not on PATH, which is why --fix-go-links
exists.

Drop golang-1.25-go from the apt list and instead check the Go on PATH, falling
back to the pinned upstream tarball from go.dev when it is missing or older than
1.25. The download is verified against a hardcoded SHA256 before anything is
unpacked, so a corrupted or tampered archive can neither be installed nor
replace an existing toolchain. Unsupported architectures fail with an
actionable message rather than a 404.

This gives every supported release the same Go install path and puts go and
gofmt on PATH without a separate step.

Signed-off-by: Muhammad Falak R Wani <falakreyaz@gmail.com>
The previous commit unconditionally downloaded Go from go.dev whenever
PATH had no Go 1.25+. That regressed Ubuntu 26.04, where golang-1.25-go
exists: hosts that can reach an apt mirror but not the public internet
went from working to failing.

Try apt first and fall back to go.dev only when the package is genuinely
unavailable. Success is decided by the filesystem (/usr/lib/go-1.25/bin/go)
rather than by parsing apt output, whose "Candidate:" label is translated
and would misfire under a non-English locale.

Since Go can now land in either root, go_root() resolves it once and both
the install path and --fix-go-links share that result.
The install gate only looked at the go on PATH. A user who had unpacked
Go into /usr/local/go without linking it into /usr/bin -- or whose links
had been removed -- would silently have that toolchain deleted and, if it
was newer than the pinned version, downgraded to 1.25.14.

Look for an installed toolchain in either root before installing anything
and reuse it when it is 1.25 or newer, so the run only re-creates the
symlinks. When /usr/local/go really is too old to keep, say so before
removing it instead of doing it silently.
The script links /usr/bin/go, but that is not necessarily the go that
runs: Ubuntu's default PATH and sudo's secure_path both list
/usr/local/bin ahead of /usr/bin, so a go left there keeps winning.

The failure that follows is remote from its cause -- tools.mk checks
go_min_version much later, from a different script, and reports only that
the version is too old. Name the shadowing binary and what it reports
while we are still in the script that can explain it.

Compare with -ef rather than by string so that reaching the same file
through the /bin -> usr/bin symlink is not mistaken for a shadow.
The document already says Azure Linux 2.0 is unsupported, then a few
lines later tells the reader what install-prereqs does on Azure Linux 2.0.

Neither half of that note is true any more. toolkit.mk refuses outright
when ID=mariner, and prerequisites-mariner.sh installs plain 'golang'
with no msft-golang handling of any kind. Remove it, and say plainly why
2.0 is out.
Go supports only its two most recent majors, so a hardcoded GO_VERSION
starts aging the day it lands. Nothing said so, and nothing said that the
minimum version is also spelled out in go.mod, the coverage workflow and
two prerequisite documents -- so the obvious next bump is a one-line edit
that leaves four other places behind.

Write the cadence and the full list of coupled locations down next to the
pin, and point the script's header comment at it.
GO_VERSION and the two GO_SHA256_* constants have to move together, and
the most likely way to get this wrong is to bump one and forget the
others. All that told you was:

    /tmp/tmp.XXXX/go.tar.gz: FAILED
    sha256sum: WARNING: 1 computed checksum did NOT match

which does not say which release was expected, which constant is stale,
where to find the right value, or whether anything was left half-installed.
It reads like a compromised download even when it is a one-line editing
mistake -- and the reverse mistake, reading a real tampering incident as a
stale constant, is worse.

Print the release, both sums, the exact constant for the architecture in
hand, and the fact that nothing was installed.
@mfrw
Muhammad Falak R Wani (mfrw) requested a review from a team as a code owner August 27, 2026 11:48
@microsoft-github-policy-service microsoft-github-policy-service Bot added documentation Improvements or additions to documentation Tools 3.0-dev PRs Destined for AzureLinux 3.0 labels Aug 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the toolkit’s Go toolchain requirements and installation paths, while aligning CI and package manifests.

Changes:

  • Raises the toolkit minimum to Go 1.25 and updates dependencies.
  • Adds reusable CI setup and Ubuntu installation logic.
  • Reorders chkconfig before dependent packages in manifests.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
toolkit/tools/go.mod Updates Go and module requirements.
toolkit/tools/go.sum Refreshes dependency checksums.
toolkit/resources/manifests/package/update_manifests.sh Corrects package generation order.
toolkit/resources/manifests/package/pkggen_core_x86_64.txt Reorders x86_64 packages.
toolkit/resources/manifests/package/pkggen_core_aarch64.txt Reorders Arm64 packages.
toolkit/docs/building/prerequisites-ubuntu.sh Adds version-aware Go installation.
toolkit/docs/building/prerequisites-ubuntu.md Documents Ubuntu Go setup and updates.
toolkit/docs/building/prerequisites-mariner.md Updates Azure Linux requirements.
.github/workflows/go-test-coverage.yml Updates the expected Go version.
.github/workflows/check-srpm-duplicates.yml Configures Go for toolkit builds.
.github/workflows/check-source-signatures.yml Configures Go and preserves its PATH.
.github/workflows/check-package-cgmanifest.yml Configures Go and preserves its PATH.
.github/workflows/check-package-builds.yml Configures Go for package checks.
.github/workflows/check-circular-deps.yml Configures Go for graph generation.
.github/actions/setup-toolkit-go/action.yml Adds shared toolkit Go setup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread toolkit/docs/building/prerequisites-ubuntu.sh Outdated
Comment thread toolkit/tools/go.mod
module github.com/microsoft/azurelinux/toolkit/tools

go 1.24.0
go 1.25.0
Comment thread toolkit/docs/building/prerequisites-mariner.md Outdated
Comment thread toolkit/docs/building/prerequisites-mariner.md
Comment on lines +119 to +122
if go_is_supported go; then
echo "Found $(go version), skipping Go installation..."
else
if go_existing_root="$(go_root)" && go_is_supported "$go_existing_root/bin/go"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of having to pass potential Go commands into go_is_supported why not make go_is_supported check all paths automatically and accept no arguments? This would also make this if-else ladder a bit cleaner.

Comment on lines +169 to +179
link_go "$go_installed_root"
fi
else
echo "Skipping installation of prerequisite packages..."
fi

# Fix go 1.24 links if requested
# Fix go 1.25 links if requested
if [ "$FIX_GO_LINKS" = true ]; then
echo "Creating Go symlinks..."
ln -vsf /usr/lib/go-1.24/bin/go /usr/bin/go
ln -vsf /usr/lib/go-1.24/bin/gofmt /usr/bin/gofmt
if go_link_root="$(go_root)"; then
echo "Creating Go symlinks from $go_link_root..."
link_go "$go_link_root"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same idea for link_go: we always pass the value from go_root into it, so why not call go_root from inside link_go and simplify things for the caller?

Also, the echo "Creating Go symlinks from $go_link_root..." call could be made from inside link_go as well. Right now we're inconsistent in printing that line btw.

Comment thread toolkit/docs/building/prerequisites-ubuntu.sh Outdated
Comment thread toolkit/docs/building/prerequisites-ubuntu.sh Outdated
Comment thread .github/actions/setup-toolkit-go/action.yml Outdated
Comment thread toolkit/docs/building/prerequisites-ubuntu.md Outdated
Comment thread toolkit/docs/building/prerequisites-ubuntu.md Outdated
Comment thread toolkit/docs/building/prerequisites-ubuntu.md Outdated
Comment thread toolkit/tools/go.mod
module github.com/microsoft/azurelinux/toolkit/tools

go 1.24.0
go 1.25.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Considering Copilot's comment: maybe let's go to at least 1.26 now?

Comment thread toolkit/tools/go.mod
go_is_supported matched go1.25 anywhere in 'go version', so go1.25rc1
satisfied it. That prerelease predates go1.25.0, which is what go.mod
asks for, so the script would decide the host was already fine, skip the
install, and leave the build to reject the toolchain later.

Require the stable form for the minimum series and keep accepting
prereleases of later ones, which really are newer.

Reported by Copilot in review.
Review feedback on three separate points:

Going from 1.25 to 1.26 was called a major bump. The major version is
the leading 1; these are minor releases. Reworded, and "two most recent
major releases" became "release series" so the page does not use the
same word for two different things a few lines apart.

The shadowed-Go note told the reader to remove the offending binary or
the build would fail. That is only true when the shadowing copy is too
old -- a newer one works fine -- so it now says what the script itself
says: remove it if the build reports an unsupported version.

The --fix-go-links description hardcoded /usr/lib/go-1.25, which is one
more place to remember on the next bump.

Also drop the Azure Linux 2.0 bullet: 2.0 is unsupported, so describing
what install-prereqs does there is noise.
Review feedback: go_is_supported took a go binary to test, link_go took
a root to link, and every caller had to work out what to pass. The
result was a nested ladder in the middle of the install block and two
separate link call sites, one of which ran even when the caller had not
asked for links and both of which ran when it had -- so a plain
install-prereqs relinked twice.

go_is_supported now answers the question the caller actually has, "is a
usable Go already here", checking PATH and both roots itself. link_go
resolves the root, prints where it is linking from, and reports the
skip when there is nothing to link, so its two callers collapse into
one. The version test that both need moved into go_version_ok. The
tarball install, which was most of the nesting, is now install_go.

go_root prefers a root that meets the minimum over one that does not,
so a stale /usr/lib/go-1.25 no longer gets linked over a good
/usr/local/go; it still falls back to whatever is installed so that
--fix-go-links can repair links to an old toolchain.

Linking now happens whenever prerequisites were installed, not only
under --fix-go-links. Neither root is on PATH -- that is why the flag
exists -- so skipping it would leave install-prereqs reporting success
with an unusable toolchain.
The GitHub runners ship Go 1.24, so every workflow that builds the Go
tools started failing the moment go.mod asked for 1.25: the toolchain
is pinned to local, which turns a too-old Go into a hard error rather
than a download.

Review feedback was to fix this the same way a developer does, by
running install-prereqs, instead of teaching CI a second way to get Go.
That also keeps the runners honest about the rest of the prerequisites
rather than relying on whatever the image happens to preinstall.

install-prereqs is safe to parse on Go 1.24 -- the version check lives
behind REBUILD_TOOLS, which defaults to n -- so there is no ordering
problem in bootstrapping it. The plain target is used, not
install-prereqs-and-configure, which would also install Docker.

go-test-coverage.yml keeps setup-go: it exists to check the pinned
version, so it should read go.mod rather than trust the same script
under test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.0-dev PRs Destined for AzureLinux 3.0 documentation Improvements or additions to documentation Tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants