7 ms·
I’m not a Rust programmer but usually one interjects to say that Rust would have prevented [some of] these issues. Does Rust in fact prevent most of these at c
by melling 6y ago
I’m not a Rust programmer but usually one interjects to say that Rust would have prevented [some of] these issues.
Does Rust in fact prevent most of these at compile time? Any that it does not?
- elwes5 6y agoI would argue that Rust removes a class of bugs. Not because the language is better, but because the compiler just does not allow it. It will not let you build your executable if that type of bug exists. For example you could still do something like a SQL injection attack using something compiled with Rust. The C compilers should be doing the same as Rust (some are, but usually at the warn level). Static analysis is not a new thing. Usually the best thing any C/C++ developer can do is crank the warn levels as high as they can go. Then set the project to error out on warn. A good code smell for a project is when you see one that has turned off warnings. Usually the reason is 'too noisy'. I always tell my junior devs the same thing 'the compiler is trying to tell you something all you have to do is listen'.
- nitrogen 6y agoThe next level after fixing all compiler warnings is running under Valgrind's different modes to catch many more memory and threading bugs.
- sanxiyn 6y agoYes it does. Not most of these, but all of them.
- cesarb 6y agoNo, that's untrue. For instance, Rust doesn't prevent an out-of-bounds access at compile time; it just converts an out-of-bounds access into a panic at run time. That is, it reliably aborts the program (or the thread), instead of reading or writing out of the bounds of the object. The same for "NULL pointer dereference"; the Rust equivalent (without using raw pointers, which require "unsafe") is calling .unwrap() on an Option<T> which has a None, which once again is not prevented at compile time, only converted into a panic at run time. Edit: note, however, that idiomatic Rust can help prevent these bugs, by using iterators instead of indexed access, and match/if-let statements instead of unwrap/expect.
- jjnoakes 6y agoThere's quite a huge difference between undefined behavior (dereferencing NULL or indexing out of bounds) which can lead to remote code execution and other super nasty bugs, and runtime checks which panic and abort the process reliably and in a well-defined way.
- pml1 6y agoreally ? You've checked all the code in question and you are a 100% sure that you would have required _zero_ unsafe code ? Drivers by their very nature require a lot of unsafe pointer passing...Having worked on a lot of embedded Linux driver code, I'm not convinced that you could do without a ton of unsafe code...which basically negates all of Rust's safety guarantees...The current architecture just doesn't lend itself well to Rust (in my opinion), so you would have to basically rewrite very large parts of the plumbing, which by its very nature would introduce a ton of new bugs...
- gpm 6y agoFor the most part rust handles pointer chasing in safe code just fine. Drivers are a fundamentally unsafe concept, like an ffi call, you're talking to hardware the compiler doesn't understand and assuming it's going to do what you want. So there will of course be some unsafe. In a well implemented driver it will also be very limited in scope and relatively easy to check. I can't vouch for the code quality (I just don't know how good it is, I had no hand in writing it, and it's not used in a production system), but I believe you can find a usb driver implementation written in rust here: https://gitlab.redox-os.org/redox-os/drivers/-/tree/master/xhcid https://gitlab.redox-os.org/redox-os/drivers/-/tree/master/x...
- pml1 6y ago>So there will of course be some unsafe. In a well implemented driver it will also be very limited in scope and relatively easy to check. I'm sure that is what the C developer thought as well...I'm not trying to be snarky, but that same arguments that are made against C code holds equally true for unsafe code... I don't think it is a reasonable position to suggest that unsafe Rust code is somehow safer than C code...
- gpm 6y agoThe point isn't that unsafe rust code is safer than C code, but that there is many orders of magnitude less unsafe rust code than c code in a driver of the same size.
- 6y ago
- gpm 6y ago- 2x double-free Yes, it would be very weird to manage to do this in rust. It would require screwing up badly in unsafe code. I guess the most likely way to fuck up unsafe code in this way would be to screw up a custom datastructure like a custom reference counted pointer (but the obvious solution is to just use the standard ones). - 8x NULL pointer dereference Yes, rust tells you when pointers might be Null (which is represented by saying the pointer is Option<PointerType> instead of just PointerType), and doesn't let you use the pointer in a way that implicitly assumes it isn't null. - 6x general protection These are generally memory errors, and are certainly undefined behavior, so yes. - 6x slab-out-of-bounds access "Yes" with a small caveat, depending on how you are using the slab it is likely that Rust doesn't force you to explicitly think about the out of bounds case and turns just silently turns the security vulnerability into a runtime error, which might be handled farther up the stack or might cause the kernel to halt. - 14x use-after-free access Yes, like double frees. The range of possible fuckups in unsafe code that cause this is probably slightly larger than the equivalent range for double frees.
- _pmf_ 6y ago> These are generally memory errors, and are certainly undefined behavior, so yes. USB registers might be in DMA buffers or another memory location that might get mapped/unmapped at any point. Not everything fits a simplistic linear memory model.
- asveikau 6y agoThis is an interesting point. Rust's borrow checker or bounds checks probably also can't know about a page table change happening underneath it. Anyone want to correct me on that?
- monocasa 6y agoIt's pretty easy to wrap those constructs in RAII wrappers to replace or augment the normal reference counting that C code would be using to keep those buffers mapped, along with associating the lifetime of the relevant buffers with that refcnt. So it won't be perfect, but you can add safety versus what you get in C. You can even add safety versus what you'd get in C++ because of the lifetimes you can associate.
- eeZah7Ux 6y agoRIIR spam is not useful. People on HN are already aware of Rust. Some are aware that many other langs are memory safe and yet that's not a reason enough to rewrite a kernel.
- gpm 6y agoYou're the first one in this thread to bring up the idea of rewriting the linux kernel in rust... the rest of us are just having a productive discussion on the degree to which a language solves a problem.
- smallstepforman 6y agoRust didnt exist when these kernels were written. A mature kernel written in Rust still doesn’t exist. Modern toolchains can effectively warn about nemory/pointer issues. I cant wait for a C++2x proposal to add Rust like memory semantics to the language - primarily to shut Rust fanboys up. Also, Rust does not warn about threading race conditions, you’d need a reference capabilities like language (Pony without ORCA) for that.