"The intention is to make these as safe as possible so that modules written in Rust require the smallest amount of `unsafe` code possible."
When writing a kernel, some unsafe somewhere is always required, on some level.
"The intention is to make these as safe as possible so that modules written in Rust require the smallest amount of `unsafe` code possible."
When writing a kernel, some unsafe somewhere is always required, on some level.
You’re saying some unsafe code is always necessary, why should that be the case? I think the big issue with wlroots was its callback-based API which is common with Linux-internal APIs as well. On a theoretical basis I’m not sure what this means for Rust. Is it simply not possible in the abstract to cast these types of APIs in a form that can be statically proven to be safe? Or is this a deficiency in the current design of Rust? Are all “callback-based” APIs inherently unsafe in Rust? Is it always theoretically possible to recast those APIs in a form that Rust can prove is safe? I would just want to understand exactly why it’s possible to write 100% safe Rust programs in user space and not in Linux kernel space.
These are the types of questions I would ask when evaluating whether or not it’s worth investing in and using Rust for my Linux driver.
Userland Rust depends on these guarantees to provide safe code, something has to implement them.
The callback thing is a red herring; it's not the fundamental issue here. Rust code can use callbacks just fine, in the general case. It also wasn't the fundamental issue with that API either.
But honestly at that point, using Rust doesn’t seem to be very much different than using C in terms of safety guarantees. It still requires a programmer capable of competently ensuring required runtime properties.
> But honestly at that point, using Rust doesn’t seem to be very much different than using C in terms of safety guarantees.
The difference is that it's limited in scope, and auditable. Even in a kernel, if you do it right, unsafe is the vast, vast minority of code. Let's be extremely generous and put it at 10% (Redox, an OS in Rust, had about 2% unsafe last I checked). That means that you still have a much, much significantly smaller space in to look for these bugs.
That’s true but it’s also slightly misleading. Any code that uses the unsafe wrappers technically must be checked and all code that uses that code must checked in turn, ad Infinitum. Misuse of the Unsafe wrapper can occur at any level. For instance, if you misuse a DMA command that corrupts memory, it’s not simply the DMA command wrapper that must be checked, the entire sequence of logic that led to the bad command being executed must also be checked.
If that is the case, then your unsafe wrappers are unsound.
Safe functions need to be impossible to use in an unsafe way or else they should marked as unsafe.
That could take the form of a runtime check that the function's invariants are maintained or a proof that the function's invariants are always maintained.