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