-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
crypto/rand: Read violates condition n == len(b) if and only if err == nil
for len(b) == 0
#67266
Comments
Here is an implementation of fix 1: |
See also #66821, which proposes to make the error always be nil instead. |
Interesting. Seems that for the most part err should be unreachable except for really old Linux kernels (and technically WASIP1 though its unlikely the underlying platform will actually error). If #66821 is approved, then this is obsolete. Its a shame the API had to be polluted with an err if that ends up being the solution. |
I don't get how this violates the claim or the reason to weaken the docs. |
The issue happens before See: https://cs.opensource.google/go/go/+/refs/tags/go1.22.3:src/crypto/rand/rand_unix.go;l=65 The call to |
If you mean |
@itstarsun You are totally right, I was conflating rand.Reader.Read and rand.Read. Thanks for catching that! |
Go version
go1.22.3
Output of
go env
in your module/workspace:N/A: Issue found in source, have not reproduced.
What did you do?
rand.Read claims:
If and only if
is sayingerr != nil -> n != len(b)
but this is not necessarily the case.What did you see happen?
For the case of
len(b) == 0
, there are codepaths in some implementations ofRead
where a non-nilerr
is returned along with ann
of 0. This violates the claim in the documentation aserr
is non-nill and the returnedn
is the same aslen(b)
An example can be found in the
rand_unix.go
implementation:If r hasn't been used yet, the call to
os.Open()
for the urandomDevice can return an error. in this scenario,Read
returns0, err
.Since no short-circuiting is in the implementation, this code path will run even for a input of length 0.
After the first run, this will not happen, as reading is delegated to
io.ReadFull
which does properly enforceif and only if
semantics as it will short circuit on a length of zero, never returning an error.What did you expect to see?
As I see it there are two possible courses of action:
Weaken the docstring's garuntee for
rand.Read
to claimRead is a helper function that calls Reader.Read using io.ReadFull. On return, n == len(b) if err == nil.
Add short-circuiting to every implementation so that a
Read
to an array of length zero will never return an error.The text was updated successfully, but these errors were encountered: