In a few words, when dealing with kernel modules and drivers (and I guess every low-level implementation), ensuring that the upper (Rust) layers are safe is still the job of a person: a person, with a great understanding of both worlds, writing the unsafe functions that glue safe-land and the rest of the kernel together.
The concept of safety is pretty different in a kernel and in a programming language. The kernel can be attacked directly with malicious calls, while it's the program created by the rust compiler that can be attacked (unless you envision Rust as a sandboxing technology, what it is absolutely not).
The safety in a programming language is mostly protecting the programmer against itself. The probability for a programmer to write this kind of code by mistake is close to zero, as opposed to UB in C or C++ that are pretty common. To make a vulnerable program with this kind of issue, the programmer would have to make them on purpose, what is unlikely unless for this kind of joke repository.
Writing safe C and C++ is even much more difficult than writing Rust code (especially with many developers). And when you are writing kernel code, both safety and performance are crucial.
As someone who has done kernel development work (though not Linux), not every part of a kernel is as filled with dragons as you make it out to be. Why would my e.g. filesystem driver need to punch a lot of deep unsafe holes down to the internals of memory management? Why can't I make use of a safe abstraction implemented using unsafe code to free myself from caring about those details?
With C, you can only do these kinds of safety guarantees with a lot of discipline. With Rust, you can offload much of your discipline to the compiler.
For kernel-level programming, I think Rust is basically the same as C or C++ in this regard. I haven't seen a kernel written in Rust where I am convinced there is a submodule that can be treated as if its correctness doesn't impact the safety of the entire kernel.
You typically don't have to write any unsafe Rust as an end user. The unsafe stuff is contained in very small and very rigorously analyzed standard library types. Which then provides you a safe interface to do all the stuff you normally do.
At the end of the day it's embedded code that's inherently unsafe, so the benefits are all in the code that belongs in the safe zone. Unsafe Rust is at best equivalent to C/C++ and at worst it's a false sense of security. Mixing safe and unsafe without a clear boundary is not something I can speak to with confidence but my gut-feeling is that it's worse than C/C++.
Even OS kernels are borderline, and it's still being figured out how exactly Rust fits, but yes we are slowly moving in that direction. Kernels have a lot of logic that qualify for the safe zone, and software engineering culture that is... let's say ahead of automotive.
That’s true, so now I see where the issue of unavoidable unsafe usage comes in. It’s not always possible to create a safe and general wrapper for all driver functionality, though in special cases maybe. I agree now that using Rust still offers something even if it can’t be guaranteed that the code is 100%. Thanks for explaining.
Look at what the people working on Rust-in-Linux are actually doing. They are writing safe Rust wrappers around internal Linux APIs that drivers use and the Linux interfaces that drivers implement. Then you can write a driver in Rust that needs little or no unsafe code of its own. Better still, then you can write ten drivers in safe Rust reusing the same glue.
And honestly, writing safe Rust wrappers around C APIs is not hard to do. The community has tons of experience with this. It does not wreck the coherence of the safe Rust code that uses those wrappers, like you seem to think.
Because most of your code can be safe? Kernels have many internal objects and data structures and algorithms that could be managed in safe code, with unsafe only used around the edges. The idea with Rust unsafe is that the unsafe portions are not 100% of the whole, and can be located relatively easily.
Which is why Rust has been accommodating the kernel by adding non-panic versions of the functions that Linus has been complaining about. Still doesn't change the fact that "safe" in this context has a technical meaning, and what Linus is describing isn't that.
I'm not sure the lack of safety is the pedagogically interesting part though. The interesting parts of writing a kernel for x86 are the low-level interfaces: assembly, I/O ports, the 8259A PIC, the fundamentals of scheduling, writing a slab allocator, and so forth. Rust allows unfettered access to those just as C does.
The lack of safety in C just means that the projects take longer to debug because the compiler doesn't catch as many mistakes; I don't think it adds much to the learning experience.
because you have to interact directly with hardware at a low level at some point (poking registers, implementing syscalls, implementing process and memory address space isolation, context switching between rings, etc), that will always be inherently unsafe.
Userland Rust depends on these guarantees to provide safe code, something has to implement them.
That not quite correct. Sure, you will have some unsafe primitives that interact with hardware. But nothing stops you from creating abstractions on top of those.
Also, `unsafe` doesn't disable all language features or the type system, it just provides an escape hatch to use raw pointers. Which, yes is quite a big step away from "normal Rust", but that's why we abstract around them.
It sure is extra and boring work, but it's entirely possible to create ergonomic APIs around unsafe low level primitives. I mean, that's how a lot of stuff gets implemented in stdlib or even in some crates. We just don't interact with it frequently, though.
Not kernel developer myself, but I've done some embedded Rust and written drivers
It is true that the boundary will be unsafe, and that's more than if it were to be all in pure Rust, but that does not change that, even when doing kernel level work, in practice it has generally been shown that unsafe code is still relatively small in amount.
Sure, but that is kind of what I mean. Safety in rust is something you actively have to think about and work around (at least some of the time). It doesn't just come for free like in python.
reply