-
Notifications
You must be signed in to change notification settings - Fork 92
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
[NCC-E005955-DBV] zebra-chain
: Unbounded Rejection Sampling with Possibility of Panics
#6338
Comments
Hey team! Please add your planning poker estimate with Zenhub @arya2 @conradoplg @dconnolly @oxarbitrage @teor2345 @upbqdn |
This doesn't block starting work on Orchard shielded coinbase mining, but it does block running on mainnet. |
The documentation of when
We shouldn't read a file to get randomness, or anything similarly unreliable, for a cryptographic RNG. Note that this method is defined on The Zcash protocols assume that it is always possible to get randomness. If an RNG returns an error, then either:
|
All of these sources of randomness are happening in a library, which in general terms should not panic, but raise an error. The consumer of the library should determine their behavior on catching such an error, such as panic, for example if they are a wallet. We don't have a wallet yet. If |
Can we document this in the code for future use cases? |
I disagree, and I've told you my considered professional opinion as a cryptographic engineer. The auditors are wrong, and a panic is the appropriate behaviour. It does not matter whether the panic happens at the library or application layer, except that the latter has slightly greater risk of the panic not actually happening, or of there being negative consequences of undefined behaviour if the failure is due to that. (If zebra didn't follow crash-only design, it might be appropriate to do a controlled shutdown that flushes data to disk for example. But it does, so that argument doesn't apply.) |
At this point a controlled shutdown isn't required in Zebra, because we commit each verified block to disk in a database transaction. So either the transaction commits and the database is valid with the new block, or it is rolled back on restart and it's valid with the old block. Losing a block doesn't matter, because we drop the last 100 blocks in memory every time we restart anyway. This would be different if we had a wallet, or any other kind of non-transactional persistent data. In that case, we'd probably want to do an atomic switch to the new version of the file (or directory): |
(This is just for info, it's not related to the specific decision about cryptographic panics.) |
Impact
The
zebra-chain
module implements random number generation for some types which are primarily used for testing, without guarding against possible panics.Description
The use of
fill_bytes()
in the code snippet below (fromzebra-chain/src/sapling/keys.rs
) can potentially cause panics. It is recommended to usetry_fill_bytes()
to catch the random number generator’s failures1.In addition, the number of sampling retries by the loop has to be bounded.
zebra/zebra-chain/src/sapling/keys.rs
Lines 176 to 196 in 5a88fe7
There is one instance where this can potentially be problematic for a full node with mining support. Generating a random
Rho
for an Orchard note uses the same unchecked RNG API.A node with mining capabilities might use this API to generate a dummy Orchard input note as a nullifier for the output note when creating a miner’s reward note:
zebra/zebra-chain/src/orchard/note.rs
Lines 59 to 69 in 161bb80
OsRng
can, in rare occasions, fail on some platforms, andthread_rng
might return awarning if it fails to reseed itself. See https://rust-random.github.io/book/guide-err.html for more
details.
Recommendation
Consider replacing the
fill_bytes()
usage withtry_fill_bytes()
and properly handle its possible failure.Location
The text was updated successfully, but these errors were encountered: