-
Notifications
You must be signed in to change notification settings - Fork 458
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
MSVC: Add support for linking against the "spectre-mitigated" CRT #673
Conversation
This doesn't seem to be totally correct. More specifically it doesn't appear to be building
I for one would argue for existing [Just in case, I'm just a cc-rs user weathering #663.] |
Ah, you're right, looks like I misread the code.
Unfortunately, appending to Additionally, we'd still need something like this for folks who don't want to run cargo/rustc in a VS Command Prompt (i.e., some way for the auto-discovery to opt-in to spectre-mitigated libs). |
The suggestion was not to append, but do nothing. Rationale basically is since one trusts
Well, the question is what exactly breaks? It should be noted that It should be noted that Rust by itself doesn't seem to have dependencies on the spectre-mitigated libraries that Microsoft provides. llvm backend effectively adds dependency to vcruntime through the exception handling mechanism, but how valuable are the mitigations in this context? Assuming there are relevant compiled in exception handlers and helpers. But in either case there is a pros side to it. The limited dependencies means that as far as Rust itself is concerned there is not much one can break by messing up the |
This PR seems reasonable to me. All it does is prefix one lib directory instead of prefixing another lib directory if a special environment variable is found. And this does indeed appear to reflect the intent of that environment variable. IMHO, changing the behaviour of how cc-rs adds to |
Once again. As it stands now, manipulating Now, it is possible to override As for opting in through an environment variable in general. Not that I'm one, but would you expect Visual Studio Code users to appreciate it? Wouldn't it be more appropriate if opt-in was more "Rust-y"? Through Cargo.toml, .cargo/config.toml or build.rs? For example, |
I'm not sure I follow you. If you're right that setting |
Keyword is that |
Again, I think you should open an issue about that. That code path will still exist whether or not this PR is merged. |
Where? On rust-lang? Maybe I will, but I feel that it would be only appropriate if "we can [only] flesh out things here" and achieve some common ground. Maybe I'm missing something which would make filing an issue inappropriate... For example it might be deemed more than sufficient to adhere to |
Open an issue here, if you like. I don't think this PR is the appropriate place to flesh out things as the issue exists regardless. |
??? Issue with what? With rustc? What would it achieve if rustc people are not here? Or issue with this PR? Is it inappropriate to discuss PR in PR thread? I don't follow, both options appear counter-productive to me. Well, never mind... |
Fair enough. Opening an issue on the main rust repo be great. |
I sense that there might be disagreement about what the issue actually is. I apologize that I failed to communicate it, but my understanding is that it would be [more than] appropriate to link with spectre-mitigated libraries specifically when you bring in C/C++ modules [presumably also compiled with (*) Formally speaking there also is CRT initialization code brought into application. But I suppose that we can agree that spectre mitigations are not essential in the CRT initialization context. Because it's fully predictable and not dependent on any secret values. Nor does a pure Rust application make it call any sensitive constructors. And for completeness, Rust also takes memcpy/move/set/cmp from CRT, but even if not linked dynamically, I don't see any difference between spetre-mitigated and default object modules. |
That's not true: under the covers rustc uses cc-rs to find the linker to use and setup the linking environment, thus any change to how cc-rs handles linking changes how every Rust program linked by rustc is built. The motivation for this change is that linking against the Spectre-mitigated CRT is compliance requirement enforced by BinSkim (https://github.com/Microsoft/binskim) - even if Rust at the moment doesn't rely on any API hardened for Spectre, that's no guarantee that it won't in the future or that any "pure" Rust application won't eventually link in non-Rust code that does. |
Ah! I was looking for it, but apparently not hard enough. Live and learn. Thanks!
Specifically in msvc environment.
Given the current state of affairs, we can be relatively confident that it won't be the result of an oversight but a conscious choice. In other words, even if there is no guarantee, it's very unlikely. |
@dot-asm I think perhaps people have been talking past each other and misunderstanding each other. Could you clarify your current stance on this PR? I have maybe gotten confused somewhere along the line. |
Even though I originally commented in ignorance of the fact that MSVC rustc itself has direct dependency on this crate (I thought that rustc had an equivalent way to invoke the vendor linker, kind of a trimmed down copy of this crate if you wish, not a direct dependency), I would still advocate against the suggestion in this specific form. Now bear with me. As already mentioned, it doesn't make any real difference if "pure" Rust application is linked with spectre-mitigated MSVC libraries. (Nor do I see this change in the foreseeable future.) And for this reason I would argue that it makes way more sense if the said libraries were linked only when it actually matters, specifically when the application actually interacts with external non-Rust code. And especially because one can arrange it in a way that is independent of rustc. So that users who care can start using the spectre-mitigated libraries at their discretion without having to wait for a future Rust release that would have to update its dependency on this crate. How? By letting |
Though formally speaking what I suggest is not in a direct conflict with the suggestion at hand. In sense that |
I admit I do not understand the objection. We already use a fair bit of magic to either use the environment or to go out of our way to find the right libraries ourselves in a way that mimics the Developer console. For example, the SDK libraries used depends on various factors, either the environment variable is used or else it searches the registry for the latest (using the sort order). I think it unlikely rustc will gain options to make all the msvc specific moving parts configurable but if it does, I see no problem in doing the right thing by default. Besides, it's really weird that currently |
As mentioned in the second remark, it's not really an objection per se, but an argument for a possibly better solution. Where "better" means self-contained in cc-rs, more reliable and more transparent for the user.
Note that my suggestion doesn't require anything of rustc that it doesn't do today.
This naturally depends on definition of "the right thing" :-) Well, not that I claim an exclusive knowledge about what it is :-) As for platform/target "crisscrossing." This ought to mean that there are situations when rustc simply does what I originally suggest, respect the |
It can't. You can't use x86 libraries to build x64 applications. |
6d394d0
to
0250abd
Compare
Using Changing how |
And the question is how big is the "if". That is how many Rust users are actually using vcvars prompt. That's the thing. Rust users don't have to use it, and suspicion is that very few would do. And I can imagine that they would appreciate the opportunity to control this through the build script more [than maintaining the discipline of invoking vcvars with right parameters]. This way there won't be ambiguity, did I compile this under vcvars or not? Or worse, did target user of my application run this under vcvars or not?
Formally speaking there is a contradiction. This merge request is all about changing how |
Again, you're asking for |
To be clear: this change doesn't require a vcvars prompt, a developer can set
Since this is controlled via an environment variable, developers can control it via a build script: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-env |
The keyword on the referred page is "when compiling the package." If you provide a library, setting the environment variable in question won't have any effect on final application link stage. Or in other words, you would have to convince your library users to set the environment variable in question in their build scripts. (And this is after you've convinced them to upgrade to a future Rust version ;-) Anyway, I've opened #687. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine by me, though I'm not very famili with windows, so I'd also like review from @thomcc
Chris, can you take a look here? You've already been active, so maybe you have opinions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it took me a minute to get back up to speed here.
Yes, I agree with these changes. We should attempt to respect the environment as much as possible. The code look good to me.
Hello @dpaoliello could you resolve the merge conflicts please? I will merge your PR once it is resolved |
Issue Details: Since VS 2017, MSVC has shipped a set of "spectre-mitigated" CRT static libs: https://devblogs.microsoft.com/cppblog/spectre-mitigations-in-msvc/ Typically these are used by opening a VS Command Prompt in "spectre mode" (https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#vcvarsall-syntax) which then sets the `LIB` environment variable to point to the directory with the spectre-mitigated libs. However, since `cc` builds its own `LIB` environment variable, it uses the non-spectre-mitigated libs even when invoked from a VS Command Prompt in "spectre mode". This causes issues when trying to build a spectre-mitigated binary using Rust, as `rustc` uses `cc` for linking. Fix Details: When `cc` detects that the `VSCMD_ARG_VCVARS_SPECTRE` environment variable is set to `spectre` (either by being run from a VS Command Prompt in "spectre mode", or users may explicitly set this themselves), it will use the spectre-mitigated lib directory when building its `LIB` environment variable.
@NobodyXu Done |
Issue Details:
Since VS 2017, MSVC has shipped a set of "spectre-mitigated" CRT static libs: https://devblogs.microsoft.com/cppblog/spectre-mitigations-in-msvc/
Typically these are used by opening a VS Command Prompt in "spectre mode" (https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#vcvarsall-syntax) which then sets the
LIB
environment variable to point to the directory with the spectre-mitigated libs. However, sincecc
prepends to theLIB
environment variable, it uses the non-spectre-mitigated libs even when invoked from a VS Command Prompt in "spectre mode". This causes issues when trying to build a spectre-mitigated binary using Rust, asrustc
usescc
for linking.Fix Details:
When
cc
detects that theVSCMD_ARG_VCVARS_SPECTRE
environment variable is set tospectre
(either by being run from a VS Command Prompt in "spectre mode", or users may explicitly set this themselves), it will use the spectre-mitigated lib directory when building itsLIB
environment variable.