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

Add allow-by-default lints for all attributes with unsafe behaviors #82499

Open
7 of 10 tasks
tarcieri opened this issue Feb 24, 2021 · 19 comments
Open
7 of 10 tasks

Add allow-by-default lints for all attributes with unsafe behaviors #82499

tarcieri opened this issue Feb 24, 2021 · 19 comments
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@tarcieri
Copy link
Contributor

tarcieri commented Feb 24, 2021

In #72188, an allow-by-default lint was added against #[no_mangle], which previously permitted unsafety even in the event that #![forbid(unsafe_code)] was used.

I think it'd be a good idea to collect a list of all such "unsafe attributes" and try to add similar lints for them on a case-by-case basis. This shouldn't be terribly difficult to do by extracting them from the Built-in attributes index from the Rust Reference.

I've started a list below. Please leave comments and I'll update it (or anyone else who has the power to do so, feel free). Items in the list with strikethrough are deemed out-of-scope.

ABI, linking, symbols, and FFI

Others?

Please leave comments with suggestions or corrections.

@jyn514
Copy link
Member

jyn514 commented Feb 24, 2021

Tangentially related: macros that "hide" the unsafe keyword behind a macro call: https://rustsec.org/advisories/RUSTSEC-2020-0011.html

@jyn514 jyn514 added the A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. label Feb 24, 2021
@jyn514
Copy link
Member

jyn514 commented Feb 24, 2021

I think all of these should be part of unsafe_code, the same way that no_mangle is. I don't think they differ significantly from no_mangle.

@jyn514 jyn514 added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Feb 24, 2021
@Nemo157
Copy link
Member

Nemo157 commented Feb 24, 2021

#[export_name] was also rolled into the same #[no_mangle] PR, since it's basically the same thing: #72209.

Given that #[link_name] can only be applied to an extern { fn } it seems that it would already be covered by the unsafety inherent in extern { fn }.

Can repr cause UB on its own? The direct UB from it I know of is repr(packed) related, but I think that's all checked at the use sites?

@nagisa
Copy link
Member

nagisa commented Feb 24, 2021

repr(packed) unsafety already has a forward-compat lint for it.

@joshtriplett
Copy link
Member

joshtriplett commented Feb 24, 2021

I don't see any obvious way that used could do anything unsafe.

Likewise repr (other than repr(packed) which is already covered).

#[link] can pull in a library, but I don't think it has any more inherent danger than extern, or a build.rs script.

I'd expect many uses of link_section to be innocuous, but it's probably possible to cause UB with it, so sure, let's add it to unsafe_code (after a crater run).

@nagisa
Copy link
Member

nagisa commented Feb 24, 2021

#[link] can pull in a library, but I don't think it has any more inherent danger than extern, or a build.rs script.

extern by itself does not link any libraries at all, so its fairly orthogonal and does not introduce any soundness concerns as far as I'm aware.

Linking libraries (even if not otherwise used) can cause implicit invocation of FFI calls through the constructors/destructors that library defines. Those can cause similar problems as calling any other FFI function, though there's nothing you can do about them either, other than not linking to the library. There was a recent issue in libloading related to this.

@tarcieri
Copy link
Contributor Author

tarcieri commented Feb 24, 2021

I'd expect many uses of link_section to be innocuous, but it's probably possible to cause UB with it, so sure, let's add it to unsafe_code (after a crater run).

link_section unsafety example I've seen:

use core::sync::atomic::{AtomicUsize, Ordering};

#[link_section = ".rodata"]
static BAD: AtomicUsize = AtomicUsize::new(0);

fn main() {
    BAD.store(42, Ordering::SeqCst);
}

@jyn514
Copy link
Member

jyn514 commented Feb 24, 2021

#[link_section = ".rodata"]
static BAD: AtomicUsize = AtomicUsize::new(0);

That uses interior mutability - could we add a more targeted lint that warns against putting anything with interior mutability (or any static mut) in .rodata?

@jonas-schievink
Copy link
Contributor

#[link_section = ".init_array"]
static BAD: usize = 0;

fn main() {}

@Lokathor
Copy link
Contributor

yeah it's easier to just forbid link_section than try to carve out exactly how it might be misused. You're never required to forbid unsafe_code anyway, so we can be overly conservative about the lint.

@chorman0773
Copy link
Contributor

#[link_section = ".rodata"]
static BAD: AtomicUsize = AtomicUsize::new(0);

That uses interior mutability - could we add a more targeted lint that warns against putting anything with interior mutability (or any static mut) in .rodata?

You can also use link_section to put functions into .rodata, or .data, or any section other than a .text section

@Lokathor
Copy link
Contributor

that's only usually UB

@chorman0773
Copy link
Contributor

I mean, I'd presume it must be at least conditionally-supported. Otherwise, it wouldn't be allowed to segfault on properly secured systems that don't allow executing .data.

@Lokathor
Copy link
Contributor

Right. Some embedded systems allow it, but you can generally assume that a "modern" system with an OS and all that won't let you play fast and loose with the program counter.

@tarcieri
Copy link
Contributor Author

tarcieri commented Mar 1, 2021

It seems like we have rough consensus that link, link_args, and link_section should get these lints.

I suppose the next step is to open an individual issue for each of them? (and at that point, perhaps this issue can be closed out unless anyone knows of any others)

@joshtriplett
Copy link
Member

Given that all three of those are link-related, I think it'd be reasonable to use one issue for all three.

The next step would likely be a PR adding them to unsafe_code, and then a crater run for that PR, to gauge impact.

@workingjubilee
Copy link
Member

#[link_args] appears to have vanished in a puff of logic: #29596

@5225225
Copy link
Contributor

5225225 commented May 16, 2022

Created #97086 for link_section

@RalfJung
Copy link
Member

Complementing the efforts tracked here, I think we should move towards the more principled solution of having a concept of 'unsafe attributes'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests