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
proposal: crypto/rand: crash process on error reading randomness #66821
Comments
Do you mean crypto/rand should panic on errors? I'm not very familiar with Go but I didn't think it used the terminology of "throwing" errors. I agree, on general language-independent robustness principles, that it should panic. |
Panics are recoverable, throw is an internal name for fatal errors. Think of it as a call to If we made crypto/rand panic that risks encouraging applications to wrap the calls in defer/recover "for robustness", when really we think it's so unlikely and so unrecoverable that applications shouldn't try. Lines 1008 to 1022 in 519f6a0
|
I think all our code already panics on crypto/rand errors (via wrapppers that don't return errors) so SGTM 😀 |
WASI 0.2 random interface thankfully does not return an error: https://github.com/WebAssembly/wasi-random/blob/main/wit/random.wit |
Sounds like we need a rand v3 |
This is the best argument for always using |
Should we keep the |
This is tempting, but I think making decisions based on kernel version is opening a can of worms. I think even the urandom fallback is reasonably reliable: the file is opened only once, so either crypto/rand never works in a given process or it always works (although it might flake across process executions, if you run out of fds before the first Read call, or if the file is removed). |
Ah I thought it opened a new file each time. Then can we use import time side effects to solve this (open the file in I get the std tries to not do that, but the overwhelming majority of cases init will start running, try |
I was thinking about that but I have no intuition as to whether the cost of calling getrandom (to check if it's available) on |
If crypto/rand is imported (even indirectly), it should be fine to make a single system call during init. I'm kinda surprised it doesn't do so already. |
Does it? On linux when there is random in auxv, then it does not even open it. Lines 44 to 58 in f17b28d
|
@mateusz834 True, on linux if we get auxv randomness we don't read /dev/urandom. |
This proposal has been added to the active column of the proposals project |
On almost all our platforms, we now have crypto/rand backends that ~never fail.
On Linux, we primarily use the getrandom(2) system call, which never fails.
getrandom()
was first available in Linux 3.17, released in October 2014. Debian oldstable is on Linux 5.10.getrandom()
can be blocked with seccomp. That's a bad (and weird) idea, and the default Docker profile doesn't do that. In that case we fall back to opening/dev/urandom
, which might fail if the file is not available or file descriptors run out.On macOS and iOS we use
arc4random()
since https://go.dev/cl/569655. From the man page:On Windows we use the ProcessPrng function. From the docs:
The BSDs use similar syscalls with similar properties (whether getrandom or getentropy) although we should switch the ones we can to arc4random.
On
js/wasm
we use getRandomValues which doesn't have documented failure modes.On WASIP1 there's
random_get
which regrettably has an error return value, making it the one platform (ignoring misconfigured Linux) where there might be errors getting platform random bytes. Since WASI rests on an underlying platform, and every underlying platform has failure-less CSPRNGs, it's hard to imagine whyrandom_get
should actually return an error.I'm proposing we make crypto/rand throw (irrecoverably crash the program) if an error occurs, and document that the error return values of
crypto/rand.Read
andcrypto/rand.Reader.Read
are always nil.This will free applications from having to do error handling for a condition that essentially can't happen, and that if it did happen is essentially not possible to handle securely by the application.
This will also allow introducing new APIs like a hypothetical
String(charset string) string
(not part of this proposal) without an error return, making them more usable and appealing.Based on a suggestion by @rsc.
/cc @golang/security @golang/proposal-review
The text was updated successfully, but these errors were encountered: