Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up#[no_mangle] is unsafe #28179
Comments
This comment has been minimized.
This comment has been minimized.
|
I think this even leads to a linker error on some platforms (depending on the situation), so in that sense I'd also be fine just having a set of all |
This comment has been minimized.
This comment has been minimized.
|
You can
This makes the playpen timeout on stable 1.2: http://is.gd/sxdUl3 |
cuviper
referenced this issue
Sep 3, 2015
Closed
rustc: malloc.c:2388: sysmalloc: Assertion failed #28180
This comment has been minimized.
This comment has been minimized.
Yeah, I'd argue that having multiply-defined |
This comment has been minimized.
This comment has been minimized.
|
I doubt there’s anything sensible (other than writing our own linker) that can be done here to truly fix the issue. I’m not against the idea of making less of these cases possible, though. e.g. #[no_mangle]
fn main(){}doesn’t work already. But most of the proposed solutions (exception being keeping more symbols in memory) sound like a non-option to me. |
tomjakubowski
referenced this issue
Sep 8, 2015
Closed
A dylib using mio on mac os x exports symbols that it probably should not. #264
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@arielb1 i didn’t say anything about safety; only about our capability to do anything about this issue. Either way, if you have to be wary of code you control unknowingly hijacking other code or doing evil things, something went very wrong where Rust (or any language, really) can’t help. |
This comment has been minimized.
This comment has been minimized.
|
JS is designed for that use-case. Rust is theoretically supposed to fill that role too, but both rustc and the type-system are way not sufficiently trustworthy for that. |
steveklabnik
added
the
A-compiler
label
Mar 11, 2016
bstrie
added
T-compiler
I-nominated
labels
Oct 19, 2016
This comment has been minimized.
This comment has been minimized.
|
I agree that unmangled symbol collisions should be a compilation error. Breakage here is extraordinarily unlikely, and the only code that it could break is code that won't be working as intended anyway, which is exactly the sort of the code that we ought to break. |
nikomatsakis
added
T-lang
and removed
T-compiler
labels
Oct 20, 2016
This comment has been minimized.
This comment has been minimized.
|
Reassigning to lang team. What a pain. |
This comment has been minimized.
This comment has been minimized.
|
triage: P-low Seems like a real problem, if not that concerning. @rust-lang/lang feels that the fix proposed by @alexcrichton in this comment is the correct one. Check at link time for duplicate |
rust-highfive
added
P-low
and removed
I-nominated
labels
Nov 3, 2016
steveklabnik
added
T-compiler
and removed
A-compiler
labels
Mar 24, 2017
Mark-Simulacrum
added
the
C-bug
label
Jul 24, 2017
retep998
referenced this issue
Jan 24, 2018
Open
Technically unsafe behavior in safe rust using #![no_main] #47685
bstrie
added
the
I-unsound 💥
label
Jan 24, 2018
This comment has been minimized.
This comment has been minimized.
|
Why is calling Also |
This comment has been minimized.
This comment has been minimized.
They can't do anything that normal functions can't do. And there isn't in theory any way to use them to violate safety (this issue is a bug; it would be totally fine in theory for
As far as I can tell, this is basically because naked functions have no guaranteed That is, the reason |
This comment has been minimized.
This comment has been minimized.
It's not the function itself that is unsafe but the call. The call to something unmangled is FFI-ish, therefore looks (and is) unsafe.
|
This comment has been minimized.
This comment has been minimized.
|
There are some other examples of abusing For example, this hack overrides #![no_main]
#[link_section=".text"]
#[no_mangle]
pub static main: [u32; 9] = [
3237986353,
3355442993,
120950088,
822083584,
252621522,
1699267333,
745499756,
1919899424,
169960556,
];Sigh. |
This comment has been minimized.
This comment has been minimized.
|
|
Centril
added
the
A-linkage
label
Nov 20, 2018
This comment has been minimized.
This comment has been minimized.
Yeah, my thinking exactly. Maybe that should forbid |
geofft commentedSep 2, 2015
On some platforms (at least GNU/Linux, but I hear Windows and several others too), if you link together two static libraries that both export a symbol of the same name, it's undefined which symbol actually gets linked. In practice on my machine, the first library seems to win. This lets you defeat type/memory safety without the
unsafekeyword, by having two crates export a#[no_mangle] pub fnwith different signatures but compatible calling conventions:Despite the stated call to
two::convert, it's actuallyone::convertthat gets called, which interprets the argument as a&'static i32. (It may be clearer to understand with this simpler example, which doesn't break type safety.)On at least GNU/Linux but not other platforms like Windows or Darwin, dynamically-linked symbols have the same ambiguity.
I don't know what the right response is here. The following options all seem pretty reasonable:
unsafekeyword.#[no_mangle]export both a mangled and un-mangled name, and have Rust crates call each other via mangled names only, on the grounds that#[no_mangle]is for external interfaces, not for crates linking to crates. ("External interfaces" includes other Rust code using FFI, but FFI is unsafe.) This is analogous to howextern "C" fns export both a Rust-ABI symbol as well as a C-ABI shim, and a direct, safe Rust call to those function happens through the Rust ABI, not through the C ABI. I'm pretty sure that all production uses of#[no_mangle]areextern "C", anyway (see e.g. #10025).#[no_mangle]on safe functions and data, and introduce a new#[unsafe_no_mangle], so it substring-matchesunsafe. (#[no_mangle]on unsafe functions or mutable statics is fine, since you need theunsafekeyword to get at them.)All of these are, I think, backwards-compatible.