A GODEBUG is actually a security risk here: most programs will start to
ignore errors from Read because they can't happen (which is the intended
behavior), but then if a program is run with GODEBUG=randcrash=0 it will
use a partial buffer in case an error occurs, which may be catastrophic.
Note that the proposal was accepted without the GODEBUG, which was only
added later.
This (partially) reverts CL 608435. I kept the tests.
Updates #66821
Change-Id: I3fd20f9cae0d34115133fe935f0cfc7a741a2662
Reviewed-on: https://go-review.googlesource.com/c/go/+/622115
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
For #66821
Change-Id: I525c308d6d6243a2bc805e819dcf40b67e52ade5
Reviewed-on: https://go-review.googlesource.com/c/go/+/608435
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
As suggested by Russ Cox, making sure we see all byte values doesn't
take long and is a superset of the existing test.
Change-Id: Ifc7f18ca4189c89a3d06d0408150a2464ce5e590
Reviewed-on: https://go-review.googlesource.com/c/go/+/608397
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This mechanism ultimately calls the same JavaScript method, but being
consistent between runtime and crypto/rand lets us reuse test coverage
across them. Also, no allocations.
Cq-Include-Trybots: luci.golang.try:gotip-js-wasm
Change-Id: I035da1ed603fbcdad61945f2b57f3fb527a959fe
Reviewed-on: https://go-review.googlesource.com/c/go/+/608396
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
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 <daniel@binaryparadox.net>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Mateusz had this idea before me in CL 578516, but it got much easier
after the recent cleanup.
It's unfortunate we lose the test coverage of batched, but the package
is significantly simpler than when we introduced it, so it should be
easier to review that everything does what it's supposed to do.
Fixes#66779
Co-authored-by: Mateusz Poliwczak <mpoliwczak34@gmail.com>
Change-Id: Id35f1172e678fec184efb0efae3631afac8121d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/602498
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
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 <roland@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Linux 6.11 supports calling getrandom() from the vDSO. It operates on a
thread-local opaque state allocated with mmap using flags specified by
the vDSO.
Opaque states are allocated in chunks, ideally ncpu at a time as a hint,
rounding up to as many fit in a complete page. On first use, a state is
assigned to an m, which owns that state, until the m exits, at which
point it is given back to the pool.
Performance appears to be quite good:
│ sec/op │ sec/op vs base │
Read/4-16 222.45n ± 3% 27.13n ± 6% -87.80% (p=0.000 n=10)
│ B/s │ B/s vs base │
Read/4-16 17.15Mi ± 3% 140.61Mi ± 6% +719.82% (p=0.000 n=10)
Fixes#69577.
Change-Id: Ib6f44e8f2f3940c94d970eaada0eb566ec297dc7
Reviewed-on: https://go-review.googlesource.com/c/go/+/614835
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Jason Donenfeld <Jason@zx2c4.com>
Reviewed-by: Paul Murphy <murp@ibm.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
It's been good since Sierra: it never fails, it's faster, it's available
on iOS (see #47812), and it still handles forks and reseeding.
On a M2 with macOS 14.3.1:
│ sec/op │ sec/op vs base │
Read/32-8 413.7n ± 3% 249.7n ± 3% -39.65% (p=0.000 n=10)
Read/4K-8 7.097µ ± 6% 1.261µ ± 2% -82.24% (p=0.000 n=10)
│ B/s │ B/s vs base │
Read/32-8 73.76Mi ± 3% 122.25Mi ± 3% +65.73% (p=0.000 n=10)
Read/4K-8 550.5Mi ± 6% 3099.0Mi ± 2% +462.99% (p=0.000 n=10)
arc4random(3) would be a good replacement for getentropy(2) on FreeBSD
and NetBSD as well, but we don't get as easy access to libc there.
Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64-longtest,gotip-darwin-amd64-nocgo,gotip-darwin-arm64_13,gotip-darwin-amd64_11,gotip-darwin-amd64_12,gotip-darwin-amd64_13,gotip-darwin-amd64_14
Change-Id: Ia76824853be92b4d1786e23592a1d2ef24d8907d
Reviewed-on: https://go-review.googlesource.com/c/go/+/569655
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
This is a subset of https://golang.org/cl/20022 with only the copyright
header lines, so the next CL will be smaller and more reviewable.
Go policy has been single space after periods in comments for some time.
The copyright header template at:
https://golang.org/doc/contribute.html#copyright
also uses a single space.
Make them all consistent.
Change-Id: Icc26c6b8495c3820da6b171ca96a74701b4a01b0
Reviewed-on: https://go-review.googlesource.com/20111
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>