-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Selectively disable sanitizer instrumentation #68164
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @davidtwco (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Is there an RFC for this that is being implemented? I've not been able to find one and this feels like it would be the type of thing that requires one? cc @rust-lang/lang |
I do not believe there is any RFC. This support has been effectively "evolving" in an experimental fashion. I think this is potentially a reasonable thing, but it would be useful at minimum to be tracking the design as it evolves -- @tmiasko has been updating the unstable book, which is great, but it seems like it'd be nice to be collecting the overall progress and (ideally) direction. (Is there a tracking issue for sanitizer support? There must be but I didn't find it right away...) |
The general tracking issue for sanitizers is #39699. I also used it as a tracking issue here, although I don't have the rights to edit the issue itself. |
OK well I at least updated that commit to link to this PR and document the existence of |
I guess I would say that I think it's ok to land this as part of that "WIP" work, @davidtwco, so long as it's all unstable, but I do think it'd be nice to decide if we want to carve out a path to stability for this (seems like it'd be good to do so?) |
I suppose I can nominate it for lang discussion, since at this point we're modifying the language, even if it's only an attribute. Let me do that. |
if let Some(list) = attr.meta_item_list() { | ||
for item in list.iter() { | ||
if item.check_name(sym::address) { | ||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_ADDRESS; | ||
} else if item.check_name(sym::memory) { | ||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_MEMORY; | ||
} else if item.check_name(sym::thread) { | ||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_THREAD; | ||
} else { | ||
tcx.sess | ||
.struct_span_err(item.span(), "invalid argument for `no_sanitize`") | ||
.note("expected one of: `address`, `memory` or `thread`") | ||
.emit(); | ||
} | ||
} | ||
} |
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.
Would be good to extract this to a function.
We discussed this at today's lang team meeting. The main concerns were:
|
Having said all that, we were basically in favor of moving forward with this, without needing an RFC at this time, as long as you address the static semantics issue (and of course make sure this all continues to be feature-gated). |
|
537aa76
to
50acfa4
Compare
@davidtwco do you feel up for reviewing this, or should we reassign? (I could take it, in theory) |
Oops, I missed the follow up comments after being nominated for discussion. |
@tmiasko In the lang team meeting, there was general consensus that |
@nikomatsakis I assume that you are referring to the Did you have any specific (even if hypothetical) extensions in mind when The |
Ostensibly one might want to pass configuration parameters to the sanitizer via the attribute. For example: |
One thing we were considering is that there are likely to be different kinds of sanitizers, and you might want a function to be sanitized in some cases but not others. I do hope that as we make progress around the unsafe code guidelines, for example, it will be standard practice for unsafe code authors to run their code using a Rust-provided sanitizer of some kind that detects violations of our aliasing rules, and (as @pnkfelix pointed out) miri could be considered a sort of sanitizer (indeed, miri is what we currently use for that purpose, though it's not ideal as it can't handle C code). The main downside I see to I guess there is also a bikeshed side to it... |
I feel that a positive variant of I would rather avoid a deeply nested variant as long as there are no use-cases for it. |
|
I guess the option option would be to push the "no" inwards
In any case, I think I'm persuaded that something along the lines of |
Remembering that Rust is sound by default, and thus that using sanitizers are substantially less necessary than in e.g., C++, how often would you need such fine-grained approaches as #[sanitizer(division_by_zero(never)]
#[sanitizer(signed_integer_overflow(never))]
fn stuff() { ... } @nikomatsakis I gave a positive example in #68164 (comment). It doesn't seem so strange to me that you could pass per-function configuration to some specific sanitizer ("when entering this function, start sanitizing with X configuration"). |
I'm persuaded by the precedent of The alternative there is probably Actually, So I'd argue (But this is again bikeshed, and we can do |
@Centril Ah, the example of I still hesitate, though, I guess because @tmiasko makes a good case that |
I'm not particularly attached to |
It seems pretty clear that there is no consensus on this question. Is it possible to land this as-is and decide the final syntax at a later point in time, prior to stabilization? Maybe by that time it will be clearer whether there are other use-cases for the syntax and what they are? |
I would be happy to defer the naming to a later point in time. |
Yeah, I'm good with that too. It would be worth adding a short summary of the notes here to the tracking issue. |
(I am doing so) |
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.
OK, did a quick review for code quality, left a few nits @tmiasko
| CodegenFnAttrFlags::NO_SANITIZE_MEMORY | ||
| CodegenFnAttrFlags::NO_SANITIZE_THREAD; | ||
if codegen_fn_attrs.flags.intersects(no_sanitize_flags) { | ||
if codegen_fn_attrs.inline == InlineAttr::Always { |
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.
We issue this lint for #[inline(always)]
, but not just a plain #[inline]
?
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.
Rustc and LLVM go out of the way to respect #[inline(always)]
attribute.
Even ignoring restrictions that would otherwise prevent inlining.
I didn't want to change that behaviour just for no-sanitize.
On the other hand the #[inline]
hint is much weaker. In the case that
no-sanitize attribute is present and sanitizer enabled, it takes the
precedence over inlining.
Add `no_sanitize` attribute that allows to opt out from sanitizer instrumentation in an annotated function.
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.
OK, seems good. I noted the key elements of the design in #39699.
@bors r+ |
📌 Commit 80adde2 has been approved by |
Selectively disable sanitizer instrumentation Add `no_sanitize` attribute that allows to opt out from sanitizer instrumentation in an annotated function.
Selectively disable sanitizer instrumentation Add `no_sanitize` attribute that allows to opt out from sanitizer instrumentation in an annotated function.
Rollup of 7 pull requests Successful merges: - #68164 (Selectively disable sanitizer instrumentation) - #68413 (Add GitHub issue templates) - #68889 (Move the `hir().krate()` method to a query and remove the `Krate` dep node) - #68909 (Respect --nocapture in panic=abort test mode) - #68910 (Add myself to .mailmap) - #68919 (Remove HashStable impl for ast::Lifetime) - #68928 (clean up E0276 explanation) Failed merges: r? @ghost
Add
no_sanitize
attribute that allows to opt out from sanitizerinstrumentation in an annotated function.