-
Notifications
You must be signed in to change notification settings - Fork 182
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
Windows: Switch to using ProcessPRNG by default. #414
Comments
It looks like this won't be quite as easy as we would like. The main issue is that
|
The fourth option would be to include your own pre-built
Note that msvc targets don't require dlltool. |
Thanks! Updated the list. I do think that maintaining a collection of @ChrisDenton I have a question. If |
@newpavlov @ChrisDenton I thinking of the following approach which would combine approaches (1) and (3).
cfg_if! {
if #[cfg(all(raw_dylib, not(target_arch = "x86")))] {
#[link(name = "bcryptprimitives", kind = "raw-dylib")]
extern "system" { fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL; }
} else if #[cfg(all(raw_dylib_x86, target_arch = "x86"))] {
#[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
extern "system" { fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL; }
} else {
unsafe fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL {
// Do the lazy DLL loading
}
}
} |
There's no problem with that. A DLL is only loaded once. Loading it more times indeed just returns the same module handle and increases the reference count. |
It would introduce a build script which will do nothing on all other targets. We may consider delaying migration to |
@newpavlov good idea. Looks like Rand 0.9's MSRV is 1.61, do you know if 1.71 would be too high? I think regardless, we should move to ProcessPrng, and just always do the DLL loading (I can put up a draft PR to see how it looks). |
I should add that the standard library is in general moving away from dynamic dll loading because it causes issues when used in some scenarios. E.g. attempting to load a library while the loader lock is already held can cause a deadlock or crash. This is especially important for std because |
Thanks for the heads up @ChrisDenton
Do you know if there is any way to call In general, I wouldn't think that the approach taken by Go and BoringSSL would break too many things in practice, but it might just be that Google doesn't run into those specific problems. It might be the case that moving to Alternatively, we could just bump the MSRV to 1.71 on Windows, and have a lower MSRV on all other platforms. |
The only way would be to use a pre-created lib file in one of the ways listed above (i.e. using the windows-targets crate or distributing a lib file with this crate).
For sure. It's fine in the vast majority of cases. It's only really TLS constructors/destructors or pre/post C main that may be an issue and only then if the DLL is not already loaded. Rust itself does not have any built-in support for TLS constructors (that's done lazily) or for running code pre/post main. However, people do use crates that implement such things. One example was someone setting up a logger when a DLL is loaded where the logger used a |
I imagine many sandboxes would block |
@josephlr wrote:
Many projects are sticking to MSRV <= 1.63 for the purpose of supporting Debian 8 which is out of mainstream support but which has some kind of extended (paid) support. Even some people who are infamous for their historical MSRV policies are at least trying to do so, so I imagine it is likely going to be difficult to move the MSRV beyond 1.63. I do support moving the MSRV to 1.63 though. |
If we want to support Rust 1.63, then using Would code based on |
I am using I expect that if |
It looks like windows-rs checks the .lib files into version control. I think we could have a script that uses libtool to extract the minimal info from the windows-rs *.lib files into a corresponding tiny set of *.lib files that we can then embed in getrandom. We could then just check in the minimal lib files into Git like windows-rs does. Because they will be tiny, it would be fine to have them all in one crate. In the interim, why not add a "msrv_1_71" feature to |
The minimum version of Windows supported in the latest version of Rust (actually, 1.78.0+) is Windows 10, so it makes sense to only use ProcessPRNG when building with Rust 1.78.0 and later. However, the minimum version of Windows supported by
Accordingly, I instead suggest having a |
Not quite. We reserve the right to bump platform requirements, if the latest stable version of Rust did it. For example, we have dropped Windows XP support, even though Rust 1.36 theoretically supports it. |
Here would be my proposal (which would simplify our implementation and maintenance burden):
|
One advantage of getting 1.0 released, is that we can simplify our MSRV policy to be "we can drop platforms or increase the MSRV in a minor version release, but won't do so in a patch release" |
This is still higher than 1.63 mentioned above and having a higher MSRV for a Tier 1 target is really undesirable. |
I think we should avoid a SemVer-incompatible version upgrade if we can.
Just to clarify my above comments, I don't object to bumping the Windows minimum supported version to Windows 10. Just, we should clarify the communication as the initial comment seemed to imply that doing so follows from what Rust 1.78 does, rather than us thinking it's a good idea independently even for older versions of Rust.
What is the benefit of a MSRV 1.65 vs 1.63? I don't see any reason to have an MSRV less than #426. I don't think there's much reason right now to have an MSRV greater than 1.57 except for this raw-dylib issue.
I think we should explore @ChrisDenton's ideas of creating a MSRV-1.63-compatible way to statically link bcryptprimitives.dll/ProcessPRNG instead. I don't know if it would actually be problematic to have an MSRV higher than 1.63 for non-Linux targets, but having different MSRVs for different targets seems likely to cause pain. |
I think we've considering bumping the MSRV at all in the past a breaking change (@newpavlov can confirm). If we stuck to that, any increase from the current MSRV 1.36 would be breaking. I'd be fine increasing the MSRV in a patch though. If you are using a rust version that old, you're almost certainly vendoring your deps as well.
Makes sense. We should drop platforms because it makes sense. Windows 10 is ~9 years old, Windows 8.1 is EOL, and we would still have a way to target Windows 7 and 8, you would just need to specify a different target.
1.65 stabilized
I think if we just depend on |
OK I updated #415 to use So we can either try to get At this point I think doing
Personally I would prefer the first option (use |
Treating conservative increases in MSRV as SemVer-breaking changes creates more problems than it solves. Realistically speaking, many, many projects I'm part of or am closely observing have a MSRV of 1.63. Including in particular cc-rs. So I think increasing the MSRV to 1.57 without bumping the SemVer minor version is the right thing to do. Note that Rust 1.57 was released Dec 2, 2021, about 2.5 years ago.
Using windows-sys/targets is much better than bumping MSRV to 1.64/1.71, regardless of how the version number of
I think that is fine. As I mentioned in the PR, there's no reason AFAICT to prefer windows-targets over windows-sys since they seem to do the version bumping in sync with each other. Using windows-targets directly seems worse. |
I don't think we should be bothering anybody with this. I feel like any effort towards that is would be wasting people's effort for no real benefit. |
Agreed on all these.
I agree that they seem to have similar versions/MSRVs, and I initially looked at using
|
Note that in those cases it's typical to use |
Your comments regarding |
It's notably more work compared to just writing (or copy-pasting) the declarations. Hopefully there is not much that can go wrong in this case. |
Fixed by #415 |
ProcessPRNG
was introduced in Windows 10, which is the minimum supported Windows for most Rust targets. Upstream change: rust-lang/rust#121337BoringSSL now uses
ProcessPRNG
: https://github.com/google/boringssl/blob/2db0eb3f96a5756298dcd7f9319e56a98585bd10/crypto/rand_extra/windows.c#L64Golang also switched to
ProcessPRNG
: https://go-review.googlesource.com/c/go/+/536235Should also help with the Chromium Sandbox: https://issues.chromium.org/issues/40277768
The text was updated successfully, but these errors were encountered: