Skip to content
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

Use getrandom for generating HashMap seed #80149

Closed
wants to merge 9 commits into from

Conversation

newpavlov
Copy link
Contributor

@newpavlov newpavlov commented Dec 18, 2020

Closes: #62079

Note that in future versions of getrandom we plan to remove Windows XP support, thus std should not update it from v0.2.0 until rust-lang/compiler-team#378 gets resolved. Also ideally it should be done together with updating wasi to v0.10.

Since the rdrand feature is enabled unconditionally, RDRAND will be used not only on SGX targets, but also on all x86(-64) targets which are not supported in getrandom by default (e.g. UEFI and Hermit targets, see rust-random/getrandom#61).

As mentioned in the previous PR discussion, if it will be deemed necessary, we (getrandom maintainers) are ready to transfer getrandom to the rust-lang organization.

Blocked on m-ou-se/getrandom#1

@rust-highfive
Copy link
Collaborator

r? @shepmaster

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 18, 2020
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@newpavlov newpavlov mentioned this pull request Dec 19, 2020
@shepmaster
Copy link
Member

This is a bit too deep for me...

r? @joshtriplett

src/tools/tidy/src/pal.rs Outdated Show resolved Hide resolved
library/std/src/sys/windows/pipe.rs Outdated Show resolved Hide resolved
library/std/src/collections/hash/map.rs Show resolved Hide resolved
@@ -2783,13 +2782,24 @@ impl RandomState {
// iteration order allows a form of DOS attack. To counter that we
// increment one of the seeds on every RandomState creation, giving
// every corresponding HashMap a different iteration order.
thread_local!(static KEYS: Cell<(u64, u64)> = {
Cell::new(sys::hashmap_random_keys())
thread_local!(static KEYS: Cell<[u64; 2]> = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change to an array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was copied from the previous PR. I think at the time I introduced this change because [u64; 2] is slightly more idiomatic than (u64, u64).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally think (u64, u64) makes more sense because it's used to fill out a RandomState which consists of two separate u64s rather than an array, but it's not a huge deal.

@newpavlov
Copy link
Contributor Author

r? @sfackler

@sfackler
Copy link
Member

@Mark-Simulacrum what are the procedures to pull in a new std dependency?

@Mark-Simulacrum Mark-Simulacrum self-assigned this Feb 10, 2021
@Mark-Simulacrum
Copy link
Member

I'll assign myself for now and get back to you soon.

@Mark-Simulacrum
Copy link
Member

Can you clarify whether you mean the mechanics (i.e., infrastructure of adding deps in terms of toml files to edit and such) or policy questions? I think the first is likely working in this PR already, and the latter would need more time on my side to answer properly.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 12, 2021
@sfackler
Copy link
Member

Yeah I'm mostly wondering about the policy side, since CI should nail down the functionality.

@bors
Copy link
Contributor

bors commented Apr 5, 2021

☔ The latest upstream changes (presumably #83890) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 5, 2021
@newpavlov
Copy link
Contributor Author

@m-ou-se
Any updates?

@m-ou-se
Copy link
Member

m-ou-se commented Apr 11, 2021

@newpavlov I reviewed the getrandom crate. See my comments here: m-ou-se/getrandom#1

Overall the quality looks good, and I'd be happy to see this under rust-lang/getrandom.

There's a few important differences in behaviour if we switch std to use getrandom, which are important do discuss before merging this PR.

Most importantly, std does not block and just falls back to urandom on Linux even if it's not yet properly seeded. (See m-ou-se/getrandom#1 (comment).) I'm not saying that's a good thing, but this will be a noticable change in behaviour.

Also, std currently simply picks (1, 2) as the random keys for hashmaps on the unsupported platforms. This PR keeps that behaviour only for specifically wasm32-unknown-unknown and aarch64-hermit, whereas right now that behaviour is selected for any unknown platform. This means that any unsupported platform other than these two will stop compiling.

@m-ou-se
Copy link
Member

m-ou-se commented Apr 11, 2021

Is there any desire to change the API? Hopefully not significantly since it has already undergone several revisions, and since rand is somewhat dependent on it (especially the error type).

I think there's one change/addition to the API that could be somewhat useful: a way to read into uninitialized buffers. E.g. by accepting a &mut [MaybeUninit<u8>] or something like proposed in rfc 2930.

all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown"),
all(target_arch = "aarch64", target_os = "hermit"),
)))]
getrandom::getrandom(&mut buf).expect("failed to get system entropy");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to convert the error to an std::io::Error first before panicking on it. That way, it uses the Debug implementation of std's Error and we don't pull in any of getrandoms display/debug code.

@bors
Copy link
Contributor

bors commented Apr 22, 2021

☔ The latest upstream changes (presumably #84411) made this pull request unmergeable. Please resolve the merge conflicts.

@crlf0710 crlf0710 added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 7, 2021
@crlf0710
Copy link
Member

crlf0710 commented May 7, 2021

Marking this as S-blocked.
@newpavlov The next steps would be dealing with m-ou-se/getrandom#1 , i guess?

@gilescope
Copy link
Contributor

"Use BCryptGenRandom instead of RtlGenRandom on Windows." merged. nice - that's great news. It's getting there...

@cameronelliott
Copy link

Will this change the availability of HashMap with regards to no_std ?
I just submitted a PR for the embedded book to clear up some confusion regarding that.
rust-embedded/book#274
rust-embedded/book#333

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2022

No, getting randomness needs interaction with an OS on every architecture other than newish x86 systems (through rdrand). #![no_std] does not assume the presence of any particular OS or even any OS at all.

@therealprof
Copy link
Contributor

No, getting randomness needs interaction with an OS on every architecture other than newish x86 systems (through rdrand). #![no_std] does not assume the presence of any particular OS or even any OS at all.

So in what way does the HashMap implementation in std differ from hashbrown which it has been based on (and which only requires alloc to work)?

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2022

libstd's HashMap is a wrapper around hashbrown that uses a hasher by default using randomness to ensure hashdos resistence.

@therealprof
Copy link
Contributor

libstd's HashMap is a wrapper around hashbrown that uses a hasher by default using randomness to ensure hashdos resistence.

Makes sense, but why can't alloc export the HashMap (and HashSet) and std only adds the wrapper on top of that?

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2022

That would make alloc::collections::HashMap and std::collections::HashMap permanently incompatible with each other. This is bound to give a lot of confusion and would prevent merging them in the future if we find a way to support this. For example by allowing the user to specify the rng using a mechanism similar to #[global_allocator].

@therealprof
Copy link
Contributor

Fair point, OTOH this is adding a bit of confusion because people can't just opt into an alloc crate to get the same collections as std provides but instead have to use an external crate which describes itself as the default HashMap of Rust. Can we add additional API to provide raw access to the hashbrown methods which and simply remove the wrapper on no_std targets?

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2022

Can we add additional API to provide raw access to the hashbrown methods which and simply remove the wrapper on no_std targets?

Hashbrown doesn't have the same stability guarantees as rust and it exports a lot of methods that are unstable or non-existent in the libstd version. Hiding those cq giving them an #[unstable] stability attribute and making sure that hashbrown api changes don't affect libstd users is one of the main purposes of the wrapper. If you keep a wrapper, but require the user to specify a hasher rather than using the hashdos resistent default hasher of std::collections::HashMap I don't see the difference with providing a separate alloc::collections::HashMap and std::collections::HashMap type.

@scottmcm
Copy link
Member

scottmcm commented Jan 8, 2023

Ideally we'd be able to move the wrapper to alloc and have the std be a type alias that sets the S = RandomState, so you could still write hasher-generic code against just alloc.

AFAIK that doesn't work right now, though, because of some coherence restrictions.

@newpavlov
Copy link
Contributor Author

This PR is significantly outdated, so I will close it. I will create a new PR after we address the @m-ou-se's review.

@newpavlov newpavlov closed this Apr 2, 2023
@newpavlov newpavlov deleted the getrandom2 branch April 2, 2023 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use getrandom crate for retrieving system entropy?