This has been covered repeatedly in the past. Rust inherently helps to prevent many types of memory related and concurrency errors.
Rust programs are not 'safe' in the sense that they cannot crash or have security bugs, but they are 'safer' in that the compiler automatically performs a series of safety checks to prevent common errors.
And note that the most serious security bugs in widespread software[1] are typically exactly these common errors. Eliminating them would have prevented nearly all of the remote execution bugs in history.
1: Widespread meaning OSes and popular platforms, not custom LOB apps where SQL injection exists on the login page.
Option types and safe pointers, and modern abstractions. Some other programming languages offer these too, but Rust attempts to do them while incurring no run-time costs.
It is effectively impossible to have an unsafe memory access error in Rust. The compiler eliminates a huge variety of bug types, including null pointer dereferences, use-after-free bugs, memory leaks, etc. All arrays are bounds-checked and rust encourages good programming practice like using abstracted list-processing mechanisms (like mapping instead of loops) and algebraic types instead of e.g. null pointers.
It is effectively impossible to have an unsafe memory access error in Rust
Please, don't say that. Lets be reasonable. Rust is great, but Rust code crashes and segfaults too, just like any language, programs have bugs, and those bugs can cause program failure.
Rust just has less of them, because it has a smart compiler. ...but it's not right to suggest that it has none.
Remember:
There is no way of ensuring that a rust program does not result in a segmentation fault or other memory or race condition as a result of unsafe code.
There is no way of ensuring a rust program does not contain any unsafe code.
I don't understand your post. If you mean 'unsafe' as in 'may misbehave' then the compiler can definitely ensure there will be no segmentation faults and there cannot be certain classes of race condition. If you mean 'unsafe' as in the keyword that lets you do dangerous things, it's trivial to check if your source has blocks marked with that keyword.
There's no way to ensure the compiler is perfect, but rust itself is not capable of certain types of errors.
You can always code the wrong algorithm, but that doesn't mean you can segfault or use after free (in the default safe mode you almost never have an excuse to leave).
You are flat put wrong, and spreading misinformation about it doesnt help anyone.
If you use any rust, and that includes dependencies and the standard library with unsafe code, bugs in the unsafe code can and do cause segmentation faults.
Its easy to say, 'well, thats a bug in the library, not a problem with rust', but thats the same as with C++ isnt it? If you can assert any code is 100% bug free then why do we care about the nice safety features in rust?
What is true is that any 'safe' code path that never enters an unsafe block in rust proveably cannot result in certain types of failures.
BUT every rust program uses unsafe code. In the standard library. In c bindings. In 'safe' pure rust dependencies (with hidden unsafe blocks). In loading dynamic libraries.
Its completely unavoidable.
What are going to do? Vet every line of every part of every dependency in the code you use? Dont be ridiculous.
Do you use rust?
..because practically speaking it does crash. Not often, sure. ...but this falacy that rust is 'provably safe' is absolutely false. Its provably false.
Thats why people saying it is unfortunate; it makes the rust community look like a bunch of clueless fanboys.
Please stick to reality. Rust has a zero cost memory management strategy and a smart compiler that helps to prevent certain types of common errors.
We dont need to step into magical fairy land to convince people rust is good. It stands on its own merit easily enough.
I guess I should have been more explicit that I was talking about the language itself (without the unsafe keyword). Not libraries written in other languages, not compilers. It's the job of theorem provers and whatnot to make those safe.
In other words I'm talking about code the programmer makes themselves.
>Its easy to say, 'well, thats a bug in the library, not a problem with rust', but thats the same as with C++ isnt it?
In C++ nothing prevents the lines I write from having memory errors. It's not the same at all.
>If you can assert any code is 100% bug free then why do we care about the nice safety features in rust?
Oh well you shouldn't do that, but you also don't have to use unsafe code willy-nilly. In C++ everything you touch is unsafe unless proven otherwise.
>What are going to do? Vet every line of every part of every dependency in the code you use?
There is no rust language without the unsafe keyword. It doesnt exist. The unwinding is unsafe. see the recent thread on /r/rust about mysterious segfaults.
Thats the point.
You cannot assert your rust program cannot crash.
Even if your code is perfect, there may be bugs in either the std library or some dependency you use that does crash.
Im not saying everyone uses unsafe code (or should) in their own code. Far from it.
Im saying that every rust program invokes unsafe code at some point.
So this myth of the 'pure rust' that is 'completely safe' is just that. A myth.
I dont understand why this is difficult idea for people to accept. Just use the good bits of rust. rust doesnt need to be 100% safe; its not, and thats completely ok.
You can write a library in rust that will never invoke unsafe code, even if you can't have an entire standalone program.
>I dont understand why this is difficult idea for people to accept. Just use the good bits of rust. rust doesnt need to be 100% safe; its not, and thats completely ok.
It's okay for now, but I'm eagerly waiting for a version where the important pieces of unsafe code can be formally verified. Give me safe unwinding, memory allocation, and sockets, and I can cover half the world.
As far as I know this isn't an especially difficult request. I could probably cobble together something right now by borrowing bits of verified C and gluing them to library-limited rust.
How often has one of your Rust programs segfaulted for you, when it wasn't a bug in your own unsafe code (as opposed to that in the standard library)? For me, the count still stands at zero.
I've been writing Rust for well over a year. I like to abuse new features and I've found many compiler bugs, but my code doesn't crash at runtime.
I'm not saying it doesn't happen, and the plural of anecdote is not data, but I think you're grossly misrepresenting Rust's practical safety benefits. That you only have to trust code in unsafe blocks, rather than all the code everywhere, is a huge benefit.
I'm certainly not trying to bash rust, and I do apologise if it comes across that way.
I just think a bit of realism makes everything look much more sincere and plausible.
As you say 'Rust cannot crash' is false. 'Rust has never crashed for me' could well be a completely true thing to say. Also, 'Its so much easier to write rust code (than say c) that doesnt crash!'
I completely ok with all of those.
..but 'you can do anything in rust and its always perfectly safe!' or 'rust programs dont have to worry about security issues' or 'It is effectively impossible to have an unsafe memory access error in Rust'?
Those are people being enthusiastic (good) but unfortunately spreading misinformation (bad) and making the rust community look bad (very bad).
I just wish people could be excited about the the things that are actually exciting about rust. I feel like this whole safety thing is a massive distraction.
fast, low level, concurrent and managed memory with no cost is both accurate and exciting about rust.
'helps avoid bugs and race conditions' isn't very exciting to me, but I acknowledge its important.
I guess 'completely provably safe!' is exciting to some people; but since its not true, Id prefer not to get people excited about rust that way.
The safety thing isn't a massive distraction. It's a major part of the point of Rust, whether it's exciting to you or not.
The graphical bindings you're using are not part of the standard library, which is why I specifically asked about that. I know there are bugs in third-party dependencies in Rust, because there are many C bindings that aren't exposed safely by those libraries. I've segfaulted using a TrueType binding library, for example, because it was not actually exposed in a way that prevented double frees. But writing a bad binding is something you can do just as easily in Ruby, or Java. The standard library is what we were originally talking about. I wouldn't disbelieve you if you said you crashed every fortnight using only standard library code, but I would probably press for details.
I am not saying Rust is "completely provably safe", but nothing is. You always have some trusted software or hardware that, if it screws up, will compromise your program. Rust's advantage is that it allows you to be explicit about what parts are trusted and what parts aren't. It vastly reduces the potential attack surface.
This is misleading. Apart from bugs in the core code (compiler and stdlib) you shouldn't be memory unsafe in an exploitable way. Even segfault from deref null should be rare. It's like saying Java isn't safe because it might call some JNI. While pedantically true, it's qualitatively different.
That's why effectively impossible is an OK statement. Unless you go out of your way, your program will not contain such bugs.
I don't accept that 'effectively impossible' means 'can happen, but probably doesn't happen very often'.
Rust has many other unsafe code paths than ffi; low level optimisations, dynamic libraries, etc.
Unless you go out of your way or are doing low level work, your code will not contain such bugs, and if you used no dependencies that do anything meaningful, what you said is plausibly true.
...but what are we trying to argue here?
That you can build a contrived rust program that doesn't crash?
Or that if you build an arbitrary program in rust, using arbitrary dependencies to do meaningful work (that will invoke a c library at some point, and talk to device drivers), that it wont crash?
In my view 'effectively impossible' is faaaaaar over stepping the bounds of reality.
Inveterate Rustacean here, and I agree with this. We need to carefully clarify the sort of safety that Rust provides in order to avoid misleading people.
Improperly implemented `unsafe` blocks can cause crashes. APIs that don't properly isolate unsafe interfaces can cause crashes. Bugs in the compiler, bugs in LLVM, and unforeseen unsoundness in the type system can cause crashes. So instead of saying "Rust makes crashes impossible", I'm starting to prefer "If you write only safe code, any crashes that occur are not your fault". A bit less comforting, but still a best-in-class guarantee for a bare-metal language (not to mention that the former claim is impossible in any language).
Furthermore, I think it's important to express to people the true role of `unsafe` blocks, which are not so much "Rust without safety" as they are "reified inline C code with a bit more safety". Rust without `unsafe` blocks could exist, but it would require an enormous amount of FFI and/or much more machinery baked into the compiler itself.
> There is no way of ensuring a rust program does not contain any unsafe code.
Sure there is. There's a compiler lint available which can disallow "unsafe" code, i.e. code which is able to create null pointer errors (and thus segfaults).
Of course, the standard library will always contain a bunch of unsafe stuff - but at least it's shared between every project, and any bugs can be fixed once, and assuming it's correct any non-unsafe code that depends on it is memory-safe.