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 upA soundness bug in std::fs #32670
Comments
notriddle
changed the title
An unfixable bug in Rust's safety guarantees
A soundness bug in std::fs
Apr 1, 2016
This comment has been minimized.
This comment has been minimized.
|
These methods are stable, they cannot be marked unsafe (almost the entire ecosystem would break). I guess things like |
This comment has been minimized.
This comment has been minimized.
|
According to the stability document:
|
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
It's the safety holes part that justifies this. This is a safety hole. It's essentially the same as the scoped thread API, only the scoped thread API was removed from Rust before it was stabilized. |
This comment has been minimized.
This comment has been minimized.
|
I wouldn't consider this a safety hole. The fact that harmless file system operations can change arbitrary memory is unfortunate, but there will always be ways to somehow circumvent Rust's safety guarantees with external "help". The scoped thread API was a process-internal API not provided by the OS but by the Rust standard lib alone, and was only unsafe because of wrong assumptions made while it was designed. |
This comment has been minimized.
This comment has been minimized.
|
Marking a stable function as unsafe would probably be covered by the quoted wording even if the function was widely used, but that doesn't mean it's a reasonable interpretation in this case. Making opening a file unsafe is so baldly ridiculous that I am asking myself if this an April's fools joke. Surely it is possible got around the symlink thing and avoid opening |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
It proposes to make |
This comment has been minimized.
This comment has been minimized.
|
You can also use safe |
This comment has been minimized.
This comment has been minimized.
|
What's worse, you could call unsafe code from safe code! This can only lead to security holes! Let's require |
This comment has been minimized.
This comment has been minimized.
|
The obvious solution is of course not to mark the methods as unsafe, but to drop Linux and Windows support and only support Redox (it's written in Rust so it must be safe) ;) |
This comment has been minimized.
This comment has been minimized.
That won't do. Redox uses FWIW I've long harbored thoughts that "safe" Rust does not go far enough. Removing ... aw crud. That requires a |
This comment has been minimized.
This comment has been minimized.
|
Except that deleting everything is not unsafe, while poking around arbitrarily in memory is. |
This comment has been minimized.
This comment has been minimized.
|
That is unfortunate short-sighted corner-cutting. |
This comment has been minimized.
This comment has been minimized.
|
Won't |
This comment has been minimized.
This comment has been minimized.
|
Nope. I get permission denied when I try to |
This comment has been minimized.
This comment has been minimized.
|
Since this seems to be an that April’s thing, and the thing’s over, closing. If my conjectures are incorrect, complain |
nagisa
closed this
Apr 2, 2016
This comment has been minimized.
This comment has been minimized.
|
tbh if the code above actually works, maybe it should have an issue for real. I think it may be considered a soundness hole, although it may not be worth fixing. It shouldn't be this issue though, the silly will detract from serious discussion. |
This comment has been minimized.
This comment has been minimized.
|
I guess this is similar to creating a safe wrapper for a C library, even if an unusual input is given, and it triggers a bug/memory error in the library, the interface should remain safe. |
This comment has been minimized.
This comment has been minimized.
|
The example works. On Sat, Apr 2, 2016, 16:06 Marcell Pardavi notifications@github.com wrote:
|
This comment has been minimized.
This comment has been minimized.
|
I guess I’ll nominate this for libs team to see (since it is technically a way to circumvent memory safety), but I doubt the outcome will be any different. Sorry for the premature close!
It doesn’t really matter IME, because the core of the issue is still here. |
nagisa
reopened this
Apr 3, 2016
nagisa
added
I-nominated
T-libs
labels
Apr 3, 2016
This comment has been minimized.
This comment has been minimized.
|
I think triggering memory unsafety from outside (using filesystem, other process, etc.) is not in scope of Rust's safety gurantee. Imagine implementing a library for controlling a repair robot. It has long flexible manupulator which can grab things, solder, connect to pins and do JTAG, etc. Should functions like But one can program the RepairBot to loop back the manipulator to the robot's own back, open the lid, solder to JTAG pins and then trigger overwriting memory, hence causing memory unsafety in Rust terms. More close-to-earth example: imagine implementing debugger like When triggering the unsafety involves some external component like filesystem, it is out of scope for Rust's safe/unsafe. You can't reliably detect a Strange loop. |
This comment has been minimized.
This comment has been minimized.
|
It's not like it's going to be fixed, whatever happens. |
notriddle
closed this
Apr 3, 2016
This comment has been minimized.
This comment has been minimized.
|
It is the responsibility of the one running the program to provide a safe interface to the operating system and hardware. Rust cannot guard against your computer literally blowing itself up because your program executed some booby-trapped instruction. |
This comment has been minimized.
This comment has been minimized.
|
Are you saying that play.rust-lang.org, not to mention basically every Linux distribution in existence, is misconfigured? |
This comment has been minimized.
This comment has been minimized.
|
Your program should be in a sandbox denying access to any file it does not need, if you don't want this to happen. |
This comment has been minimized.
This comment has been minimized.
|
@vks, Undefined behaviour on the other hand can lead to malware code execution (which, for example, sends private data from |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
I do not buy the suggestion that memory unsafety is okay if it's caused by interacting badly with the operating system or specific hardware. Certainly it is unacceptable for a safe Rust library to say, invoke the The point of a safe Rust interface is to offer precisely that, a memory-safe interface, an API that Rust code can use without worry of memory unsafety, in all circumstances, whatever silly mistake the programmer might make. The point is not to assign blame but to isolate the unsafety and fight it, so that the end result are safer, more reliable programs. Therefore, functions that are not marked Now, clearly, Rust cannot take care of everything. It can't prevent side channel attacks. It can't prevent authentification code from containing a logical bug that gives every user full privileges. It can't forsee a hardware error in future generations of CPUs that will cause it to write to address If a safe function in the Rust library is called, and it ends up overwriting memory of the running process, then that is a memory safety issue. It doesn't matter one bit if it goes through the OS, specifically, through the mock |
This comment has been minimized.
This comment has been minimized.
|
That's cool and all, but there's a reason I closed this bug; this particular safety hole is infeasible to fix. Other "memory-safe" languages (Python, Haskell, Java) share this hole, so there probably no easy way to fix it, and the hard ways of fixing it would get in the way far more than they help. (Marking the file open APIs unsafe would just be stupid.) |
This comment has been minimized.
This comment has been minimized.
|
@notriddle It probably wasn't clear from my rant, but I am standing by my earlier position of "this may very well be not worth fixing". Like you, I am skeptical that it can be reasonably prevented. But several recent comments in this thread seem to veer too far into another direction, sounding like "apologists" for memory unsafety so to speak. I am strongly of the opinion that leaving such a hole open must come from a pragmatist "We'd like to fix it but it's just not practical" place, not from a "It's hard to trigger and not our fault so whatevs :shrug:" direction. |
This comment has been minimized.
This comment has been minimized.
sanmai-NL
commented
Jan 3, 2018
•
|
@notriddle: can’t |
This comment has been minimized.
This comment has been minimized.
|
@sanmai-NL , What if Also imagine an operating system that has socket analogue of The main issue that OS-s allow memory introspection and it should not be considered Rust-unsafe. Even more intricate example: imagine a robotics library for a electronics repair robot that allows user code to control special manipulators that move around using motors and connect to pins (e.g. JTAG) of various boards around. But what if we command it to connect to JTAG of the same board that is controlling the robot ("self-repair mode")? Now we can read/write any memory, including one mapped to Rust process. Does it make motor-controlling or pin digital input/ouput functions Rust-unsafe? |
This comment has been minimized.
This comment has been minimized.
|
There are also limitations/defects in common hardware, such as those exploited by https://en.wikipedia.org/wiki/Row_hammer to modify arbitrary memory. Does rowhammer imply that all memory accesses should be considered unsafe? XD |
notriddle commentedApr 1, 2016
This program writes to arbitrary memory, violating Rust's safety guarantees, despite using no unsafe code:
Because the filesystem APIs cannot be made safe (blocking
/procpaths specifically will not work, because symlinks can be created to it),File::create,File::open, andOpenOptions::openshould be marked unsafe. I am working on an RFC for that right now.