-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
all: require Linux 3.2 kernel for Go 1.24 #67001
Comments
I'm ambivalent about this trend in general. For Go, it also pushes a bit against the compatibility promise. I've been burned multiple times by manufacturers dropping support for old hardware, requiring expensive upgrade purchases that provide no return benefit to me. I still run a 32-bit x86 Mac in the lab because without it I cannot control an important piece of kit that can only be interfaced to an old mac OS version. I can't even connect it to the network for fear some update will render my equipment non-working. While I appreciate the implied - if uncertain - value of "newer is safer, newer is better", what is the actual cost to the project of letting Go binaries run on old OSes? That seems a better way to evaluate this proposal. |
The cost to the project in general is continued maintenance and testing of code paths working around the lack of features from the (relatively) newer kernels. We don't do a great job of testing Go on these old kernels as it is. It probably only kind of works. I should have mentioned that Linux 3.2 was released 12 years ago. It is not bleeding edge by any means. According to https://en.wikipedia.org/wiki/Linux_kernel_version_history, the final 2.6.x kernel was 2.6.32.71 in 2016. We are talking about dropping support for kernels that are very old. |
Talking to @FiloSottile about #66821, it sounds like moving to 3.17 (~2014) as the minimum would let us avoid needing to open /dev/urandom ever, because 3.17 added getrandom(2). That would be a better choice than 3.2. |
This proposal has been added to the active column of the proposals project |
In the way of additional data points, a few popular and older distribution versions and their associated kernel versions (all of which IMO point in favor of this proposal at 3.2 and even at 3.17 👍):
It's a bit hard to browse, but even more aggregated data at https://repology.org/project/linux/versions (I dug up this information to convince myself this was sane and figured it was worth sharing 👍 ❤️) Edit: and see #60792 (comment) for a much longer form of similar data with many more details! 😄 ❤️ |
Red Hat Enterprise Linux 7 is on kernel 3.10 and it's maintenance ends 30 June 2024. Red Hat offers Extended Lifecycle Support until 30 June 2028. Gcloud CLI supports RHEL7 and it includes Golang binaries. You may want to clarify how long Gcloud CLI plans to support RHEL7. |
The RHEL 7.9 OS has a kernel version 3.10.0 and is supported until 2028-06. Changing the minimum version to 3.17 may impact services running on this OS. https://distrowatch.com/table.php?distribution=redhat&pkglist=true&version=rhel-7.9#pkglist |
The RHEL 7 kernel had getrandom backported in 2017, per https://access.redhat.com/errata/RHSA-2017:1842:
So in practice Go programs would continue to work on RHEL 7 if the only 3.10+ feature used is getrandom. |
Thanks for the added details. I think we can say 3.10+getrandom is fine too. |
Have all remaining concerns about this proposal been addressed? The proposal is to require Linux 3.17 starting in Go 1.24, |
I think 3.17 (or 3.10+getrandom) is doable and reasonable. I had a minor concern with Debian 8 codename Jessie, released April 2015, which is still in extended long term support by freexian (paid support, until mid 2025, possibly mid 2026 at most if customers pay for it), because it had 3.16.7. But even during normal LTS there were backports available with kernel 4.9, and now freexian recommends their backports (due to security updates mostly) maintained by them of kernel 4.19 and 5.10. And anybody still running so old system (initial release 2015-04-26, official EOL 2020-07; and now we are at Debian 12, so many many major releases behind), can just stick to old code, or continue using older Go to maintain any software they run. So even Debian 8 with ELTS would be fine with this 3.17+ requirement in practice. (Debian 9 codename Stretch, was released with 4.9.30, on 2017-06-18, already out of normal LTS, and ELTS from freexian until 2027). So, good to go with 3.17 |
Based on the discussion above, this proposal seems like a likely accept. The proposal is to require Linux 3.17 starting in Go 1.24, |
No change in consensus, so accepted. 🎉 The proposal is to require Linux 3.17 starting in Go 1.24, |
I still support this, but in the interest of being aware of expected breakage, Synology apparently ships Linux 3.10 without getrandom() in recent (current?) firmwares. The "good" news is that apparently even glibc gave up on that, so a C application invoking |
Change https://go.dev/cl/602495 mentions this issue: |
@bradfitz See the comment #67001 (comment). I seem to recall that you've mentioned Synology before. |
For #67001 Change-Id: Ic0b91cd393046c53e41908e8dbbe2ab5fb6b8a74 Reviewed-on: https://go-review.googlesource.com/c/go/+/588216 Reviewed-by: Ian Lance Taylor <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Tobias Klauser <[email protected]> Auto-Submit: Tobias Klauser <[email protected]>
We have 10,329 7-day active users using Synology devices with kernels older than 3.17:
And then we also have 6,026 other active Linux users NOT using Synology running kernels older than 3.17. So 16,355 active users who would be impacted by this change. |
And then we also have 6,026 other active Linux users NOT using Synology running kernels older than 3.17.
How many of those are RHEL 7 and derivatives (which backported getrandom)?
|
If we need to drop back to 3.2 to match Rust and glibc, with the understanding that it will mean keeping some crypto code that opens /dev/urandom for a while longer (and crashes if that fails), then I'm okay with that if others are. It is a very tiny amount of code, and getrandom appears to be the only thing we were hoping for after 3.2. I don't see too much point to dropping behind what Rust and glibc now require, though. |
I wonder how many of these older versions are actually using recent versions of Go? Seems to me that if people don’t or can’t upgrade to newer kernels, maybe they aren’t keeping up to date with Go releases as well… I’m guessing the telemetry data won’t help here? |
The challenge is that it isn't just a constraint of the system running Go, but on the systems running the Go programs, so the telemetry won't capture that sample set. (I still think the change is fine, to be clear, just trying to help explain why it's Complicated and doesn't necessarily relate to systems using the Go toolchain directly very much.) |
@meling For a case like Synology, this is users who want to run a new Go program on their Synology system, but it may not be straightforward for them to update that system to a newer kernel. |
Change https://go.dev/cl/608175 mentions this issue: |
After discussion with @FiloSottile we've agreed to drop down to Linux 3.2 as the minimum version for future versions of Go, matching glibc and Rust. crypto/rand will have a fallback to open /dev/urandom for randomness (OCLOEXEC, of course) when getrandom returns ENOSYS. |
Change https://go.dev/cl/609178 mentions this issue: |
Linux added the prlimit system call in version 2.6.36. As our minimum Linux kernel version is now 3.2, simplify the various getrlimit/setlrimit implementations to just always use prlimit. For #67001 Change-Id: I2512c21c947d0bc83f8f9077c143163fd8d83be3 Reviewed-on: https://go-review.googlesource.com/c/go/+/609178 Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Tobias Klauser <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
Now that the decision is to only require Linux 3.2, should we update https://go.dev/doc/go1.23? It still says:
|
@mvdan Thanks for pointing that out. https://go.dev/cl/611943 |
Change https://go.dev/cl/611943 mentions this issue: |
Originally we thought we were going to require 3.17, but we backed off. For golang/go#67001 Change-Id: I9979f018f534638e911bfefb17747973c3948781 Reviewed-on: https://go-review.googlesource.com/c/website/+/611943 Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Daniel Martí <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Tim King <[email protected]>
From our weekly review, this issue is still open and marked as a release blocker just because we need to make sure it ends up in the Go 1.24 release notes. |
The fallback was reachable on - Linux, where starting in Go 1.24 we require a kernel with getrandom(2), see #67001. - FreeBSD, which added getrandom(2) in FreeBSD 12.0, which we require since Go 1.19. - OpenBSD, which added getentropy(2) in OpenBSD 5.6, and we only support the latest version. - DragonFly BSD, which has getrandom(2) and where we support only the latest version. - NetBSD, where we switched to kern.arandom in CL 511036, available since NetBSD 4.0. - illumos, which has getrandom(2). (Supported versions unclear.) - Solaris, which had getrandom(2) at least since Oracle Solaris 11.4. - AIX, which... ugh, fine, but that code is now in rand_aix.go. At the end of the day the platform-specific code is just a global func(b []byte) error, so simplified the package around that assumption. This also includes the following change, which used to be a separate CL. crypto/rand: improve getrandom batching and retry logic The previous logic assumed getrandom never returned short, and then applied stricter-than-necessary batch size limits, presumably to avoid short returns. This was still not sufficient because above 256 bytes getrandom(2) can be interrupted by a signal and return short *or* it can simply return EINTR if the pool is not initialized (regardless of buffer size). https://man.archlinux.org/man/getrandom.2#Interruption_by_a_signal_handler Whether this ever failed in practice is unknown: it would have been masked by the /dev/urandom fallback before. Instead, we apply buffer size limits only where necessary (really, only Solaris in practice and FreeBSD in theory) and then handle gracefully short returns and EINTR. Change-Id: I8677b457aab68a8fb6137a3b43538efc62eb7c93 It turns out that we now know that large getrandom calls *did* fail in practice, falling back on /dev/urandom, because when we removed the fallback TestBidiStreamReverseProxy with its 4KiB read started failing. https://cr-buildbucket.appspot.com/build/8740779846954406033 For #66821 Change-Id: Iaca62997604f326501a51401cdc2659c2790ff22 Reviewed-on: https://go-review.googlesource.com/c/go/+/602495 Reviewed-by: Roland Shoemaker <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Daniel McCarney <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
Reintroduce the urandom fallback, but this time with a robust set of tests all pointing guns at each other, including a seccomp'd respawn simulating the lack of getrandom, to make sure the fallback both works and is never hit unexpectedly. Unlike the Go 1.23 fallback, the new one only triggers on ENOSYS (which is cached by unix.GetRandom) and doesn't handle the EAGAIN errors we never got an explanation for. We still crash the program from Read if we have to go to /dev/urandom and we fail to open it. For #67001 Updates #66821 Tested on legacy SlowBots (without plan9 and illumos, which don't work): TRY=aix-ppc64,dragonfly-amd64,freebsd-amd64,freebsd-386,netbsd-amd64 Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64_14,gotip-solaris-amd64,gotip-js-wasm,gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero,gotip-windows-amd64,gotip-windows-386,gotip-linux-386,gotip-linux-amd64-longtest-race,gotip-linux-amd64-boringcrypto Change-Id: Idecc96a18cd6363087f5b2a4671c6fd1c41a3b0e Reviewed-on: https://go-review.googlesource.com/c/go/+/608175 Reviewed-by: Daniel McCarney <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
Change https://go.dev/cl/622015 mentions this issue: |
The minimum Linux kernel version for Go 1.24 is now set to 3.2. Updates #67001 For #68545 Change-Id: I509f09c8ed7f3067af14066cf139008db0cb06ba Reviewed-on: https://go-review.googlesource.com/c/go/+/622015 Auto-Submit: Carlos Amedee <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
The release notes have been submitted. Please feel free to re-open this issue if any changes were missed. |
In 2021 in #45964 we moved the minimum Linux kernel version to 2.6.32.
There is a good summary from @baryluk about what we use from newer kernels at #60792 (comment).
@mdempsky points out in #60792 (comment) that Rust and glibc decided on a minimum kernel version of 3.2 last year.
Adopting 3.2 as Go's minimum seems reasonable given the rest of the Linux ecosystem doing the same.
I propose we announce this in Go 1.23 and make the change in Go 1.24. That will still be a year or so behind glibc and Rust, and the announcement will create time for people to speak up if they are affected and cannot upgrade.
Really everyone should be on newer kernels for security updates anyway.
The text was updated successfully, but these errors were encountered: