Proposal Details
Currently when we set the random seed on Linux, the runtime's fallback path needs to open, read and then close "/dev/urandom". This requires 3 system calls. A single getrandom does the same thing and is simpler than using open() -> read() -> closefd()
.
67001 Raised the minimum supported Linux kernel version to 3.17+, so that "getrandom(2)" can be used in the runtime package and we can do all the things in one system call now.
We can wrap getrandom with internal/runtime/syscall.Syscall6
so that the helper function readRandom
will no longer need to open and close "/dev/urandom".
Since Go 1.24 will only support Linux kernel 3.17+ (or 3.10+ with getrandom patches), I think a fallback is unnecessary (and a fallback can easily be added if someone needs it).
Comment From: gabyhelp
Related Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: seankhliao
I don't think a proposal is necessary as there are no user facing changes? Crashing on unavailability seems ok given #66821
Comment From: randall77
On linux at least, the runtime does not normally call getrandom. We use the auxv random data at startup. The readRandom path is kind of a fallback. (I'm not sure precisely when linux gives us the auxv. But I imagine most modern linuxes do - that path has been in the codebase for a while.)
Comment From: apocelipes
On linux at least, the runtime does not normally call getrandom. We use the auxv random data at startup. The readRandom path is kind of a fallback. (I'm not sure precisely when linux gives us the auxv. But I imagine most modern linuxes do - that path has been in the codebase for a while.)
Yes, but I think it's also worth to simplify the fallback path. All this changes will be at most a middle size CL.
Comment From: randall77
Yeah, no problem, I was not arguing against the proposed change. Simplification is good. Just mentioning it probably won't affect any behavior.
Comment From: randall77
Given #67001 is accepted, I don't think this needs to be a proposal. Taking out of the proposal process.
Comment From: apocelipes
Given #67001 is accepted, I don't think this needs to be a proposal. Taking out of the proposal process.
Thanks. I'd like to send a CL to implement this when the next development window opens.
Comment From: Jorropo
I think this is a duplicate part of #66821, all of the content of this issue seems to be covered by #66821 already.
Comment From: randall77
I think #66821 is about crypto/rand
, not the runtime's internal randomness.
There's also math/rand
and math/rand/v2
, not sure if those interact with a source of randomness or not.
Comment From: mauri870
Looks like math/rand/v2 uses runtime.rand for the random source of top level functions
https://github.com/golang/go/blob/71f9dbb1e409a28680f40c60fad5a386ed92a096/src/math/rand/v2/rand.go#L254-L259
Not only that, but runtime.rand is used all over the stdlib, net, os, sync, math/rand, hashing maps in the runtime, etc.
Both runtime.rand and the random source for an M (mrandinit) use globalRand that is setup in randinit, which might be using readRandom if there is no startupRand. On linux we seem to always use auxv as startupRand.
https://github.com/golang/go/blob/71f9dbb1e409a28680f40c60fad5a386ed92a096/src/runtime/os_linux.go#L245-L250
I'm not sure if the readRandom path is ever taken for linux.
Comment From: mauri870
Looks like sysauxv has some cases where startupRand is not set, not sure how common it is:
https://github.com/golang/go/blob/71f9dbb1e409a28680f40c60fad5a386ed92a096/src/runtime/os_linux.go#L304-L309
In these cases it will use readRandom.
Edit: NVM, I did not saw there was a for loop here. So I think startupRand is always initialized.
Comment From: gopherbot
Change https://go.dev/cl/608436 mentions this issue: runtime: use arc4random_buf() for readRandom
Comment From: gopherbot
Change https://go.dev/cl/612715 mentions this issue: runtime: use getrandom(2) for readRandom on Linux